You can use TweenService with linear interpolation.
Number all of your points with rising numbers from start to end. Then use a for loop to tween the NPC based on a movement speed parameter calulated with the distance between the points to get a move time value.
for waypoint = 1, #waypoints:GetChildren() do
mob.MovingTo.Value = waypoint
humanoid:MoveTo(waypoints[waypoint].Position)
humanoid.MoveToFinished:Wait()
end
even with a 10 second wait it just hovers in place and doesnt full touch it
As I said, this is being caused by MoveToFinished’s timeout, at the end of the page there’s a function to prevent this.
local function MoveTo(humanoid: Humanoid, targetPoint: Vector3, andThen: () -> any?)
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()
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
local Humanoid -- your humanoid
local TargetPos -- your target position
MoveTo(Humanoid, TargetPos, function()
print("Finished")
end)
How would I implemnt this into my code? Here it is;
function mobHandler.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = map.Waypoints
for waypoint = 1, #waypoints:GetChildren() do
mob.MovingTo.Value = waypoint
humanoid:MoveTo(waypoints[waypoint].Position)
humanoid.MoveToFinished:Wait()
end
mob:Destroy()
map.Base.Humanoid:TakeDamage(humanoid.Health)
end
local function Iterate(humanoid, t: { Vector3 } , n: number?, andThen: any?)
n = n or 1
assert(n)
if n > #t then if andThen then andThen() end return end -- if all waypoints have been reached
MoveTo(humanoid, t[n].Position, function()
Iterate(t, n + 1, andThen)
end)
end
Also, instead of what you’re doing I would opt for an iterative loop using ipairs/pairs, but with your example you could skip this and opt for the function’s recursion.
Iterate(humanoid, waypoints:GetChildren(), 1, function ()
mob:Destroy()
map.Base.Humanoid:TakeDamage(humanoid.Health)
end)
local function Iterate(humanoid, t: { Vector3 } , n: number?, andThen: any?)
n = n or 1
assert(n)
if n > #t then if andThen then andThen() end return end -- if all waypoints have been reached
MoveTo(humanoid, t[n].Position, function()
Iterate(t, n + 1, andThen)
end)
end
function mobHandler.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = map.Waypoints
Iterate(humanoid, waypoints:GetChildren(), 1, function ()
mob:Destroy()
map.Base.Humanoid:TakeDamage(humanoid.Health)
end)
end
The part: MoveTo(humanoid, t[n].Position, function() errors moveto