So I've asked this before, but after messing around a little bit I think I found why, but I don't know what to do about it, so here is the part of the script that seems to fail:
-- Chase local plr_HRP = plr_character.HumanoidRootPart local destination = plr_HRP.Position local beginning = HRP.Position local path = PathfindingS:CreatePath(PathInfo) path:ComputeAsync(beginning, destination) if path.Status == Enum.PathStatus.Success then local waypoints = path:GetWaypoints() for cry, waypoint in pairs(waypoints) do if waypoints.Action == Enum.PathWaypointAction.Jump then Hum.Jump = true end Hum:MoveTo(waypoint.Position) Hum.MoveToFinished:Wait() end else Hum:MoveTo(HRP.Position) end
So this is what it looks like when i say it glitches: (gif) https://gyazo.com/cfd6fd7e9b350809dd352f2ed6cac2e9
Now, this doesn't happen if i remove Hum.MoveToFinished:Wait()
But I mean, that is a necessary part of a chase script no? for the enemy to wait before going to the next waypoint
What could i do?
If for some reason you need to see the full script, here it is:
--- Services --- local Plrs = game:GetService("Players") local RunS = game:GetService("RunService") local PathfindingS = game:GetService("PathfindingService") --- Variables --- local char = script.Parent.Parent local Hum = char.Humanoid local HRP = char.HumanoidRootPart local CanJump = false local FOV = 50 local CharSize = char:GetExtentsSize() local PathInfo = { ModelRadius = (CharSize.X + CharSize.Z)/4, ModelHeight = CharSize.Y, ModelCanJump = CanJump } --- Initialization --- HRP:SetNetworkOwner(nil) --- Functions --- local function FindClosestPlr() local players = {} local ClosestDistance = math.huge local target for index, targetplr in pairs(Plrs:GetPlayers()) do local TargetChar = targetplr.Character if TargetChar == nil then continue end local distance = (TargetChar.HumanoidRootPart.Position - HRP.Position) if distance.Magnitude <= FOV then table.insert(players, { Magnitude = distance.Magnitude, Player = targetplr }) end end for i, entry in pairs(players) do local magnitude = entry.Magnitude local player = entry.Player if magnitude < ClosestDistance then ClosestDistance = magnitude target = player end end return target end function Chase() local plr = FindClosestPlr() if plr == nil then return end if plr.Character.Humanoid.Health <= 0 then return end local plr_character = plr.Character or plr.CharacterAdded:Wait() local plr_humanoid = plr_character.Humanoid -- Chase local plr_HRP = plr_character.HumanoidRootPart local destination = plr_HRP.Position local beginning = HRP.Position local path = PathfindingS:CreatePath(PathInfo) path:ComputeAsync(beginning, destination) if path.Status == Enum.PathStatus.Success then local waypoints = path:GetWaypoints() for cry, waypoint in pairs(waypoints) do if waypoints.Action == Enum.PathWaypointAction.Jump then Hum.Jump = true end Hum:MoveTo(waypoint.Position) Hum.MoveToFinished:Wait() end else Hum:MoveTo(HRP.Position) end end --- Connections --- RunS.Heartbeat:Connect(Chase)
The problem is because you're using Run Service's heartbeat signal which isn't ideal as signals create new threads meaning it won't yield for it to complete, which means it will try to get to a new waypoint, but it is also trying to get to an old waypoint.
So instead of using heartbeat signal you can make the function call itself when it ends as well as before it returns (add a wait to prevent script from timing out) and add the chase function at the end of the script. Example:
function Chase() if plr == nil then wait(1) Chase() return end -- Code here Chase() end Chase()
Also, this will cause the NPC to stop which I don't know how fix. It will also yield the thread but to fix this you can just wrap it in coroutine.
Full script after fix (not wrapped in coroutine):
--- Services --- local Plrs = game:GetService("Players") local RunS = game:GetService("RunService") local PathfindingS = game:GetService("PathfindingService") --- Variables --- local char = script.Parent.Parent local Hum = char.Humanoid local HRP = char.HumanoidRootPart local CanJump = false local FOV = 50 local CharSize = char:GetExtentsSize() local PathInfo = { ModelRadius = (CharSize.X + CharSize.Z)/4, ModelHeight = CharSize.Y, ModelCanJump = CanJump } --- Initialization --- HRP:SetNetworkOwner(nil) --- Functions --- local function FindClosestPlr() local players = {} local ClosestDistance = math.huge local target for index, targetplr in pairs(Plrs:GetPlayers()) do local TargetChar = targetplr.Character if TargetChar == nil then continue end local distance = (TargetChar.HumanoidRootPart.Position - HRP.Position) if distance.Magnitude <= FOV then table.insert(players, { Magnitude = distance.Magnitude, Player = targetplr }) end end for i, entry in pairs(players) do local magnitude = entry.Magnitude local player = entry.Player if magnitude < ClosestDistance then ClosestDistance = magnitude target = player end end return target end function Chase() local plr = FindClosestPlr() if plr == nil then wait(1) Chase() return end local plr_character = plr.Character or plr.CharacterAdded:Wait() local plr_humanoid = plr_character.Humanoid if plr_humanoid.Health <= 0 then wait(1) Chase() return end -- Chase local plr_HRP = plr_character.HumanoidRootPart local destination = plr_HRP.Position local beginning = HRP.Position local path = PathfindingS:CreatePath(PathInfo) path:ComputeAsync(beginning, destination) if path.Status == Enum.PathStatus.Success then local waypoints = path:GetWaypoints() for cry, waypoint in pairs(waypoints) do if waypoints.Action == Enum.PathWaypointAction.Jump then Hum.Jump = true end Hum:MoveTo(waypoint.Position) Hum.MoveToFinished:Wait() end else Hum:MoveTo(HRP.Position) end Chase() end --- Call Functions --- Chase()