I have this module script that controls a rigs movement across the map by moving it to each waypoint in order. The problem is, the slower rigs aren’t getting to the further away waypoints before trying to move to the next one. I have tried looking around on the DevForum, but haven’t found anything useful.
Here is the module script that controls the movement (This is only the related part of the module script):
function mob.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = workspace.Waypoints
for waypoint=1, #waypoints:GetChildren() do
humanoid:MoveTo(waypoints[waypoint].Position)
humanoid.MoveToFinished:Wait()
end
mob:Destroy()
end
yea MoveToFinished event is not reliable at least i have faced this issue many times. Maybe do this
for _, anim in ipairs(animator:GetPlayingAnimationTracks()) do
anim:Stop()
endfunction mob.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = workspace.Waypoints
for waypoint=1, #waypoints:GetChildren() do
while (humanoid.Parent.HumanoidRootPart.Position - waypoints[waypoint].Position).Magnitude < 1 do
wait(1)
humanoid:MoveTo(waypoints[waypoint].Position)
humanoid.MoveToFinished:Wait()
if (humanoid.Parent.HumanoidRootPart.Position - waypoints[waypoint].Position).Magnitude < 1 then
break
end
end
end
mob:Destroy()
end
this will wait for the MoveToFinished event and then checks if player have reached the waypoint by checking the distance between the waypoint and the player and breaks the loop if it have reached it.
for _, anim in ipairs(animator:GetPlayingAnimationTracks()) do
anim:Stop()
endfunction mob.Move(mob, map)
Above, there is no mention to the animator, so the script will automatically break. Also, there is a line with endfunction, which I don’t know what that is.
I’m not sure where this part of the script came from, but ignoring that, the rest seems okay, although you are trying to compare a Vector3 distance, which won’t work. I fixed that error, but now he won’t move away from the first checkpoint.
function mob.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = workspace.Waypoints
for waypoint = 1, #waypoints:GetChildren() do
local destination = waypoints[waypoint].Position
local distanceToWaypoint = (humanoid.Parent.HumanoidRootPart.Position - destination).magnitude
while distanceToWaypoint > 1 do
humanoid:MoveTo(destination)
humanoid.MoveToFinished:Wait()
distanceToWaypoint = (humanoid.Parent.HumanoidRootPart.Position - destination).magnitude
end
end
mob:Destroy()
end
Try printing the distanceToWaypoint maybe the distanceToWaypoint is more than one. And now idts using checking the distance between them would be a good option.
function mob.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = workspace.Waypoints
for waypoint = 1, #waypoints:GetChildren() do
local destination = waypoints[waypoint].Position
local Connection
Connection = waypoints[waypoint].Touched:Connect(function() ---checking if the NPC have touched/reached the waypoint. If yes then set the attribute true
waypoints[waypoint]:SetAttribute("WayPoint_Reached",true)
Connection:Disconnect() ---Disconnect the connection cause no use of now. And a new connection will be made for the next NPC in the nect ittereation
Connection = nil
end)
while true do
if waypoints[waypoint]:GetAttribute("WayPoint_Reached") then break end ---if the NPC have reached the waypoint the look will stop
humanoid:MoveTo(destination)
humanoid.MoveToFinished:Wait()
end
waypoints[waypoint]:SetAttribute("WayPoint_Reached",false) ---set the WayPoint_Reached Attribute to false for the next NPC
end
mob:Destroy()
end
For the most part this works! The only problem is that once the first mob gets to the second waypoint, and the rest of them get to the second waypoint, they stop moving.
You can yield until the mob has reached the waypoint.
function getDistance(start : Vector3, location : Vector3)
return (start - location)
end
function ForceMoveTo(humanoid : Humanoid, location : Vector3)
local reached = false
local rootpart = humanoid.RootPart
local offset = getDistance(location, rootpart.Position).Unit
while not reached do
humanoid:MoveTo(location + offset)
reached = humanoid.MoveToFinished:Wait()
end
if getDistance(rootpart.Position, location).Magnitude > 1 then
return ForceMoveTo(humanoid, location)
end
end
Did you add this onto the MoveTo function I already had, or does this replace it? Because just replacing it, I got this error ServerScriptService.Main.Mob:44: invalid argument #1 to ‘wrap’ (function expected, got nil)
I’m not quite sure what you meant by that. Its a code on my current system and I pasted it here so you can use it as a reference. Modifying your script should be easy.
function getDistance(start : Vector3, location : Vector3)
return (start - location)
end
function ForceMoveTo(humanoid : Humanoid, location : Vector3)
local reached = false
local rootpart = humanoid.RootPart
local offset = getDistance(location, rootpart.Position).Unit
while not reached do
humanoid:MoveTo(location + offset)
reached = humanoid.MoveToFinished:Wait()
end
if getDistance(rootpart.Position, location).Magnitude > 1 then
return ForceMoveTo(humanoid, location)
end
end
function mob.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = workspace.Waypoints
for waypoint=1, #waypoints:GetChildren() do
ForceMoveTo(humanoid, waypoints[waypoint].Position)
end
mob:Destroy()
end
Here is the entire module script that controls the mob movement. I’m not getting any errors, but the mobs aren’t moving past the start (1st checkpoint).
local physicsService = game:GetService("PhysicsService")
local serverStorage = game:GetService("ServerStorage")
local mob = {}
function getDistance(start : Vector3, location : Vector3)
return (start - location)
end
function ForceMoveTo(humanoid : Humanoid, location : Vector3)
local reached = false
local rootpart = humanoid.RootPart
local offset = getDistance(location, rootpart.Position).Unit
while not reached do
humanoid:MoveTo(location + offset)
reached = humanoid.MoveToFinished:Wait()
end
if getDistance(rootpart.Position, location).Magnitude > 1 then
return ForceMoveTo(humanoid, location)
end
end
function mob.Move(mob, map)
local humanoid = mob:WaitForChild("Humanoid")
local waypoints = workspace.Waypoints
for waypoint=1, #waypoints:GetChildren() do
ForceMoveTo(humanoid, waypoints[waypoint].Position)
end
mob:Destroy()
end
function mob.Spawn(name, quantity, map)
local mobExists = serverStorage.SpawnMobs:FindFirstChild(name)
if mobExists then
for i=1, quantity do
task.wait(1)
local newMob = mobExists:Clone()
newMob.HumanoidRootPart:PivotTo(workspace.Waypoints[1].CFrame)
newMob.Parent = workspace.Mobs
newMob.HumanoidRootPart:SetNetworkOwner(nil)
for i, object in ipairs(newMob:GetDescendants()) do
if object:IsA("BasePart") then
object.CollisionGroup = "Mob"
end
end
newMob.Humanoid.Died:Connect(function()
task.wait(0.7)
newMob:Destroy()
end)
coroutine.wrap(mob.Move)(newMob, map)
end
else
warn("Requested Mob Does Not Exist", name)
end
end
return mob