Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I get an NPC to actively smoothly follow a player (with PathFinding)?

Asked by 4 years ago
Edited 4 years ago

So I have gotten all the pathfinding to work properly, my problem is having the NPC actively follow the player. What I think is happening is when I update the path the NPC wants to go to the first waypoint however sometimes that waypoint is behind them which causes them to turn around for a second.

So my question is ... can someone help me find a way to have the NPC's pathfinding update constantly to be able to smoothly follow a moving player?

Whats happening: https://gyazo.com/6b9bdb221942eb9baa2a7d9ed19b8cd7

Full script

local pathFinding = game:GetService("PathfindingService")
local npc = script.Parent
local humanoid = npc.Humanoid
local maxDistance = 50
local target
local wayPoints = {}
local path
local currentWaypoint

function findTarget()
    local newDistance
    local closestdistance
    local closestPlayer
    for i,v in pairs(game.Players:GetPlayers())do
        if v.Character then
            newDistance = (v.Character.HumanoidRootPart.Position-npc.Torso.Position).Magnitude
            if newDistance <= maxDistance then
                if closestdistance then
                    if newDistance < closestdistance then
                        closestdistance = newDistance
                        closestPlayer = v.Character.HumanoidRootPart
                    end
                else
                    closestdistance = newDistance
                    closestPlayer = v.Character.HumanoidRootPart
                end
            end
        end
    end
    return closestPlayer
end

function createPath()
    target = findTarget()
    if target then
        path = pathFinding:CreatePath()
        path:ComputeAsync(npc.Torso.Position,target.Position)
        if path.Status == Enum.PathStatus.Success then
            wayPoints = {}
            wayPoints = path:GetWaypoints()
            currentWaypoint = 1--setting this to 1 is what I think causes a problem
            for i,v in pairs(workspace.Paths:GetChildren())do
                v:Destroy()
            end
            for i,v in pairs(wayPoints)do
                local part = Instance.new("Part")
                part.Size = Vector3.new(.5,.5,.5)
                part.Position = v.Position
                part.BrickColor = BrickColor.new("Institutional white")
                part.Anchored = true
                part.Parent = workspace.Paths
            end
            moveTo()
        else
            print('path failed')
        end
    else 
        print('no player found')
    end
end

function moveTo()   
    if wayPoints[currentWaypoint].Action == Enum.PathWaypointAction.Jump then
        humanoid.Jump = true
    end
    humanoid:MoveTo(wayPoints[currentWaypoint].Position)
end

function onWaypointReached(reached)
    if reached and currentWaypoint < #wayPoints then
        currentWaypoint = currentWaypoint + 1
        humanoid:MoveTo(wayPoints[currentWaypoint].Position)
    end
end

createPath()
humanoid.MoveToFinished:Connect(onWaypointReached)
while true do--I am assuming there is a better way of doing this
    createPath()
    wait()
end

P.S .. sorry if this is a bad explanation :/

Answer this question