Ad
Log in to vote
0

[SOLVED] How do I make this pathfinding AI, create path more often?

Asked by 11 months ago
Edited 11 months ago

TO MAKE IT MORE SIMPLE HERE IS A MODEL OF THE AI:

https://web.roblox.com/library/8293330612/Test

What could be happening is in the code there is a for i, v in pairs()waypoints do this is causes it to repeat waypoint creation. This means it will not recreate the path therefore going to the players last location or it could be there is a humanoid.MoveToFinished:Wait() at line 32 stopping the script making it un able to repeat the path after removing the humanoid.MoveToFinished:Wait() it will constantly update the path but travel in a straight line towards the player

here is the full script (I didn't make the torso finding bit) I have had a few try's at fixing which I'm doing right now but I struggle to find a fix

local pathService = game:GetService("PathfindingService")
local humanoid = script.Parent.NOOB
humanoid.Parent.PrimaryPart:SetNetworkOwner(nil)

function findNearestTorso(pos)
    local list = game.Workspace:children()
    local torso = nil
    local dist = 800
    local temp = nil
    local human = nil
    local temp2 = nil
    for x = 1, #list do
        temp2 = list[x]
        if (temp2.className == "Model") and (temp2 ~= script.Parent) then
            temp = temp2:findFirstChild("HumanoidRootPart")
            human = temp2:findFirstChild("Humanoid")
            if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
                if (temp.Position - pos).magnitude < dist then
                    torso = temp
                    dist = (temp.Position - pos).magnitude
                end
            end
        end
    end
    return torso
end

local function move(v)


    humanoid:MoveTo(v.Position)
    humanoid.MoveToFinished:Wait()
    end





local path
while true do
    wait(0.1)
local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
    if target ~= nil then

        path = pathService:CreatePath()

        path:ComputeAsync(script.Parent.HumanoidRootPart.Position, target.Position)

        local waypoints = path:GetWaypoints()
        if path.Status == Enum.PathStatus.Success then

            for i,v in pairs(waypoints) do

                local part = Instance.new("Part", workspace)
                part.Anchored = true
                part.CanCollide = false
                part.Material = Enum.Material.Neon
                part.Position = v.Position
                part.Size = Vector3.new(0.6,0.6,0.6)
                part.Shape = "Ball"

                    if v.Action == Enum.PathWaypointAction.Jump then
                    humanoid.Jump = true

                    end

                    move(v)

            end
        end
    end
end

0
one of my ideas of how to fix this was to pick up and repeat getting one waypoint at a time instead of multiple but that could cause the ai to constantly pause and I struggled to work out how to do that tommymcoco1 39 — 11mo

1 answer

Log in to vote
3
Answered by
TGazza 1306 Moderation Voter
11 months ago

Just re-wrote your AI with something I had in storage.

Code:

local Me = script.Parent

local MyBase = Me:WaitForChild("HumanoidRootPart",10)
local Humanoid = Me:WaitForChild("NOOB",10)
Me.PrimaryPart:SetNetworkOwner(nil)

local Index = 3 -- this is needed to start from 3 otherwise the npc will turn away then back!.
local Points = {}

function findNearestTorso(pos)
    local list = game.Workspace:children()
    local torso = nil
    local dist = 800
    local temp = nil
    local human = nil
    local temp2 = nil
    for x = 1, #list do
        temp2 = list[x]
        if (temp2.className == "Model") and (temp2 ~= script.Parent) then
            temp = temp2:findFirstChild("HumanoidRootPart")
            human = temp2:findFirstChild("Humanoid")
            if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
                if (temp.Position - pos).magnitude < dist then
                    torso = temp
                    dist = (temp.Position - pos).magnitude
                end
            end
        end
    end
    return torso
end



local blockedConnection

local function computePathtoV3(Target)
    if(MyBase ~= nil) then


        local PFS = game:GetService("PathfindingService")

        local path = PFS:CreatePath(
            {
                AgentRadius = 4, -- This tells how wide or FAT your npc is!
                AgentHeight = 8, -- How high they can jump (i think!)
                AgentCanJump = true, -- and Can they jump?
                Costs = { -- this can be used to define prefered path or not by setting the values from 0
                    --// the higher this number the more chance your npc will advoid it!


                    --[[ 
                        to use this you need a part in the workspace 
                        with a PathfindingModifier with the ModifierId set to this id (KillBrick)
                        then this Ai will avioid this part!
                        you can change this name just make sure this key matches exactly the one set in the modifireId
                        in your PathfindingModifier object! 
                    ]]
                    KillBrick = math.huge
                }
            }
        )

        local success, errorMessage = pcall(function()
            path:ComputeAsync(MyBase.Position, Target)
        end)

        blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
            -- Check if the obstacle is further down the path
            print(blockedWaypointIndex, Index)
            if blockedWaypointIndex >= Index then
                -- Stop detecting path blockage until path is re-computed
                blockedConnection:Disconnect()
                -- Call function to re-compute new path
                computePathtoV3(Target)
            end
        end)

        if success and path.Status == Enum.PathStatus.Success then
            return path:GetWaypoints()
        elseif(path.Status == Enum.PathStatus.NoPath) then

            computePathtoV3(Target)
        end

    end
    return {}
end
local Goal
local MyPath


local GIndex = 1

local DebugPathBits = {}
local Debug = true
while true do

    Goal = findNearestTorso(MyBase.Position)
    if(Goal ~= nil) then

    MyPath = computePathtoV3(Goal.Position) 
        if(Debug == true) then
            for k,v in pairs(DebugPathBits) do
                v:Destroy()
            end
            table.clear(DebugPathBits)
        for i,v in pairs(MyPath) do

            local part = Instance.new("Part", workspace)
            part.Anchored = true
            part.CanCollide = false
            part.Material = Enum.Material.Neon
            part.Position = v.Position
            part.Size = Vector3.new(0.6,0.6,0.6)
            part.Shape = "Ball"
            DebugPathBits[i] = part
        end
    end


    if(Index <= #MyPath) then
        local Dist = (MyBase.Position - MyPath[Index].Position).magnitude
        --print(Humanoid:GetState())
        if  MyPath[Index].Action == Enum.PathWaypointAction.Jump 
            and Humanoid:GetState() ~= Enum.HumanoidStateType.Freefall then

            Humanoid:MoveTo(MyPath[Index].Position)

            Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
            Humanoid.MoveToFinished:wait()

        end
        Humanoid:MoveTo(MyPath[Index].Position)

        if(Dist <= 2) then -- using Distance to make sure our ai gets to this point!
            Index = Index +1
        end

    else

        GIndex = GIndex +1 <= #Points and GIndex +1 or 1
        Index = 3
        end
    end
    wait()
end

There's still a chance of the Ai getting stuck while jumping, but it should work.

Also, Happy Holidays! :) and if you need help just let me know :)

0
Thank you so much ill try add a unstuck function, but this works so well exactly what I was looking for tommymcoco1 39 — 11mo
0
to stop it getting stuck between jumps switch Humanoid:MoveTo(MyPath[Index].Position) and Humanoid.MoveToFinished:wait() tommymcoco1 39 — 11mo
Ad

Answer this question