Hello, I have been messing around with pathfinding and finding it quite fun. However, recently I noticed my script has been causing them to, what I believe, is finish each movement early, causing the animation to reset midway. Also, it seems to just stop sometimes. I have it programmed to stop, but I have removed it and it persists. I tested it on a fresh model and it still happens.
Script:
local pathfindingService = game:GetService(“PathfindingService”)
local body = script.Parent.Torso or script.Parent.HumanoidRootPart
local humanoid = script.Parent.Humanoid
local body = script.Parent:FindFirstChild(“HumanoidRootPart”) or script.Parent:FindFirstChild(“Torso”) --Works on R6 and R15
local destination = game.Workspace.EndGoal.Position
local timeToStop = 0
local timeToBeat = 0
local start = game.Workspace.Start
local player = game.Players.LocalPlayer
local path = pathfindingService:CreatePath()
while true do
–Teleport onto start
body.CFrame = start.CFrame
--Make the path
path:ComputeAsync(body.Position, destination) --Goes body position(torso) to destination
local waypoints = path:GetWaypoints()
local startTime = os.date("*t" )
--Go to movepoint, wait to hit it, then go to the next, all ther way through
for k, waypoint in pairs(waypoints) do
local startTime = os.date("*t")
local stopMovement = 0
stopMovement = math.random(1,20)
if stopMovement == 10 then
timeToStop = math.random(.5,2)
wait(timeToStop)
turnAroundNow = math.random(1,60)
if turnAroundNow == 1 then
turnDistance = math.random(20,50)
for i = 1, turnDistance do
body.CFrame = body.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(5), 0)
wait()
end
wait(1)
for i = 1, turnDistance do
body.CFrame = body.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(-5), 0)
wait()
end
end
else humanoid:MoveTo(waypoint.Position)
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
humanoid.MoveToFinished:Wait()
wait()
end
end
local finishTime = os.date("*t")
if (startTime.min ~= finishTime.min) then
finishTime.sec = finishTime.sec + 60
end
startTime = startTime.sec
finishTime = finishTime.sec
local timeItTook = finishTime - startTime
print("It took the AI " .. timeItTook .. " seconds to reach the finish")
body.CFrame = start.CFrame
Also, I’m new to posting on the forum, so knowing why the code block formatting did not cover all the code would be a plus, if you don’t mind my asking.
--Make the path
path:ComputeAsync(body.Position, destination) --Goes body position(torso) to destination
local waypoints = path:GetWaypoints()
local startTime = os.date("*t" )
--Go to movepoint, wait to hit it, then go to the next, all ther way through
for k, waypoint in pairs(waypoints) do
local startTime = os.date("*t")
local stopMovement = 0
stopMovement = math.random(1,20)
if stopMovement == 10 then
timeToStop = math.random(.5,2)
wait(timeToStop)
turnAroundNow = math.random(1,60)
if turnAroundNow == 1 then
turnDistance = math.random(20,50)
for i = 1, turnDistance do
body.CFrame = body.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(5), 0)
wait()
end
wait(1)
for i = 1, turnDistance do
body.CFrame = body.CFrame * CFrame.fromEulerAnglesXYZ(0, math.rad(-5), 0)
wait()
end
end
else humanoid:MoveTo(waypoint.Position)
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
--humanoid.MoveToFinished:Wait()
local timeOut = 0
local myRoot = humanoid.Parent.HumanoidRootPart
--local part = createpart(waypoint.Position)
repeat
humanoid:MoveTo(waypoint.Position)
wait(.05)
timeOut = timeOut +.05
until timeOut > 1 or (myRoot.Position - waypoint.Position).magnitude < 5
--local timeOut = myHuman.MoveToFinished:Wait(1)
if timeOut > 1 then -- if not timeOut then
-- whatever you want here
end
wait()
end
end
local finishTime = os.date("*t")
if (startTime.min ~= finishTime.min) then
finishTime.sec = finishTime.sec + 60
end
startTime = startTime.sec
finishTime = finishTime.sec
local timeItTook = finishTime - startTime
print("It took the AI " .. timeItTook .. " seconds to reach the finish")
body.CFrame = start.CFrame
MoveToFinished:Wait() is the cause of the stuttering, so if you replace it with a loop that counts for a total of 1 second and calculates if the NPC is < 5 studs it will be more efficient. Note that this is not the best solution as the NPC will sometimes try moving towards a path that may get stuck in a corner of a brick or try walking into a wall if the map is small with lots of obstacles.
It only does this in play mode btw, in run the animation kinda of breaks because the loop is acting weird is my guess, don’t know how to describe it, but I don’t really mind that as much as I do it basically stopping every second once it gets to the turns.
humanoid:MoveTo(waypoint.Position)
wait(.05)
timeOut = timeOut +.05
until timeOut > 1 or (myRoot.Position - waypoint.Position).magnitude < 5
Are you telling it to wait in between each waypoint to add a timeout?
Try putting the timeout code outside of the loop moving the character.
Also I know a bug similar to this that affects my humanoids in studio when I use MoveTo(). It should work fine in a live game if your problem is related.
Well the purpose of it is incase the NPC doesn’t reach the waypoint at a certain time, it will either recalculate the destination or whatever you insert into the the if-statement. I’ve used this for my AI with the pathfinding services and its worked for my intentions as obstacles are not too crazy, when my NPC gets stuck on a brick, the timeout will determine if it is stuck and decide based on the following functions. I’m aware its not the best technique and is sorta buggy. This method is preferably meant to keep the npc moving and not stutter.
This seems to have worked, although I will either have to lighten up and widen the maze a bit, or mess with it myself, because at the current state he is hitting walls like a player would holding w, and only moving on because he was angled enough to eventually keep going. Here and there however, he just face plants and gets stuck.I think I could probably fix it by have him move back or something, but I should have what I need now, unless you have any tips for aiding the AI in fixing itself.
Now the AI hits walls but won’t face plant no matter how long I wait. I think I will just stick with this, as it is technically a working, not too weird looking AI.