the character in my tower defense game stops short of the waypoints that have been outlined and begins to the next one, making his walk diagonal. I want to make it so the character can only start moving to the next waypoint if he is in the middle of part
Is your code waiting for the HumanoidRootPart to touch the target waypoint part? Looks like the humanoid switches direction as soon as the root part touches it. The only other reasons are :MoveTo() timing out, or it just decides it has reached the goal already for some unknown reason.
In my experience, I’ve found :MoveTo() somewhat unreliable especially when detecting if it’s already at the target position, so I just use :Move(targetDirection) until the humanoid is close enough to move to the next waypoint.
here is the code, it doesn’t wait for the humanoid root part to touch. it waits for the humanoid to say it’s done
function move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = map.Waypoints
for waypoint = 1, #waypoints:GetChildren() do
local currentwaypoint = waypoints[waypoint]
local waypointpos = currentwaypoint.Position
humanoid:MoveTo(waypointpos, currentwaypoint)
humanoid.MoveToFinished:Wait()
end
mob:Destroy()
end
The Humanoid:MoveTo() function has a timeout of 8 seconds, so if it doesn’t reach the waypoint in 8 seconds it will think that it reached the waypoint
local function moveTo(humanoid, targetPoint, andThen)
local targetReached = false
-- listen for the humanoid reaching its target
local connection
connection = humanoid.MoveToFinished:Connect(function(reached)
targetReached = true
connection:Disconnect()
connection = nil
if andThen then
andThen(reached)
end
end)
-- start walking
humanoid:MoveTo(targetPoint)
-- execute on a new thread so as to not yield function
task.spawn(function()
while not targetReached do
-- does the humanoid still exist?
if not (humanoid and humanoid.Parent) then
break
end
-- has the target changed?
if humanoid.WalkToPoint ~= targetPoint then
break
end
-- refresh the timeout
humanoid:MoveTo(targetPoint)
task.wait(6)
end
-- disconnect the connection if it is still connected
if connection then
connection:Disconnect()
connection = nil
end
end)
end
Use this custom move to function to remove the timeout.
Create the function that i sent in the start of the script and replace the original moveto function with the custom function. Pass in the humanoid and the target point
It runs the andThen function when the moving is finished, in your case you don’t need and andThen function so you can leave it empty. But don’t forget to remove the task.spawn function to let your script wait until the movement is done
local function moveTo(humanoid, targetPoint, andThen)
local targetReached = false
-- listen for the humanoid reaching its target
local connection
connection = humanoid.MoveToFinished:Connect(function(reached)
targetReached = true
connection:Disconnect()
connection = nil
if andThen then
andThen(reached)
end
end)
-- start walking
humanoid:MoveTo(targetPoint)
-- execute on a new thread so as to not yield function
while not targetReached do
-- does the humanoid still exist?
if not (humanoid and humanoid.Parent) then
break
end
-- has the target changed?
if humanoid.WalkToPoint ~= targetPoint then
break
end
-- refresh the timeout
humanoid:MoveTo(targetPoint)
task.wait(6)
end
-- disconnect the connection if it is still connected
if connection then
connection:Disconnect()
connection = nil
end
end