I did not, let me try something.
Doesnt change it still broken, what do I do?
Welp, im coming back from school so i cant really help you atm. Hopefully someone reaches out to you soon.
Maybe send a screenshot on how the NPC behaves when pathing
see they do not fully touch it and go on to the next one
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
You could try move to way point
I made a quick function for your iteration;
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)
Ok i think i found the solution, try making the agent pathfinding width smaller.
See here:
https://developer.roblox.com/en-us/api-reference/function/PathfindingService/CreatePath
(This also implies you change your script to use PathfindingService instead of MoveTo)
So like this?
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
Here is the entire code so far;
--By Rjj259_YT
--Main Variables--
local physicsService = game:GetService("PhysicsService")
local serverStorage = game:GetService("ServerStorage")
local mobHandler = {}
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
function mobHandler.Spawn(name, quantity,map)
local mobExists = serverStorage.mobs:FindFirstChild(name)
if mobExists then
for i = 1, quantity do
task.wait(0.5)
local cloneMob = mobExists:Clone()
cloneMob.HumanoidRootPart.CFrame = map.Start.CFrame
cloneMob.Parent = workspace.Mobs
cloneMob.HumanoidRootPart:SetNetworkOwner(nil)
local movingTo = Instance.new("IntValue")
movingTo.Name = "MovingTo"
movingTo.Parent = cloneMob
for i, object in ipairs(cloneMob:GetDescendants()) do
if object:IsA("BasePart") then
physicsService:SetPartCollisionGroup(object, "Mob")
end
end
cloneMob.Humanoid.Died:Connect(function()
task.wait(0.5)
cloneMob:Destroy()
end)
coroutine.wrap(mobHandler.Move)(cloneMob, map)
end
else
warn("Requested mob does not exist: ", name)
end
end
return mobHandler
You’ve not declared the MoveTo
function shown in this post: MoveTo Tiny NPC - #15 by Sarchyx. It’s also warning because I forgot to change the table’s values typecheck, you can remove it if you want.
t: { BasePart }
It still does it and when it gets to the spot where it turns before hitting it an error:
I also delcared it now:
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)
This is the line:
if n > #t then if andThen then andThen() end return end -- if all waypoints have been reached
My bad, when the function calls Iterate()
again the humanoid isn’t passed as first argument.
Iterate(humanoid, t, n + 1, andThen)
still doesnt touch
How about you just move the point a bit further.
sometimes charcaters are different size so that would not work for all.
Do you have any scenario where your maps will not be flat? Like perhaps a map with a hill or something?
If your maps are relatively simple or you’re willing to add waypoints before and after hills (and along the hill if the hill is not a straight line) then you could get away with not using Humanoids at all. Humanoids are actually quite expensive and require physical simulation which will generally start to slow a game down after the first 100 or so humanoid characters (pre-optimizations such as disabling most of the humanoid states).
If you are willing to put in more waypoints you can pretty easily use a much faster method such as the TweenService. Here’s an example of how you could do what you’re wanting using the tween service and some recursive CFraming (for smooth turning).
WaypointWalkersExample.rbxl (39.0 KB)
Yeah! I was planning on using tween service just had no idea how to implement it with my code