I’m using PathfindingService
to make this monster wander around my map until it’s near a player, then it chases the player. My problem is that for the first 2 minutes, it works perfectly (video 1), but then it starts stuttering (video 2). I found temporary fixes like moving the monster up half a stud, recalculating the route, and teleporting to an open room when the monster hasn’t moved far enough in an amount of time, but the monster will always go back to stuttering after those 2 minutes. I have no idea why.
(Video 1)
(Video 2)
Function MoveToSpawn()
moves the monster to a spawn point
Code:
local function FollowPath(destination)
task.wait()
local continuing = nil
destination, continuing = GetDestination(destination) -- This is a function that checks if a player is nearby, if not, it checks if the monster is currently going to a random room, if it is not, it chooses a room
local humanoid = MONSTER_OBJ.Humanoid
local rootPart = MONSTER_OBJ.PrimaryPart
local success, errorMessage = true, nil
if (not continuing) then
-- Go to new random room or close by player
success, errorMessage = pcall(function()
PATH:ComputeAsync(rootPart.Position, destination)
end)
if (success and PATH.Status == Enum.PathStatus.Success) then
WAYPOINTS = PATH:GetWaypoints()
if (BLOCKED_CONNECTION) then
BLOCKED_CONNECTION:Disconnect()
end
BLOCKED_CONNECTION = PATH.Blocked:Connect(function(blockedWaypointIndex)
-- Path blocked, stop everything and recalculate
if (blockedWaypointIndex >= NEXT_WAYPOINT_INDEX) then
REACHED_CONNECTION:Disconnect()
BLOCKED_CONNECTION:Disconnect()
WAYPOINTS = nil
NEXT_WAYPOINT_INDEX = nil
REACHED_CONNECTION = nil
BLOCKED_CONNECTION = nil
destination = nil
end
end)
if (not REACHED_CONNECTION) then
REACHED_CONNECTION = humanoid.MoveToFinished:Connect(function(reached)
if (reached and NEXT_WAYPOINT_INDEX+1 < #WAYPOINTS) then
NEXT_WAYPOINT_INDEX += 1
if (WAYPOINTS[NEXT_WAYPOINT_INDEX].Action == Enum.PathWaypointAction.Jump) then
MONSTER_OBJ.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
humanoid:MoveTo(WAYPOINTS[NEXT_WAYPOINT_INDEX].Position)
else
-- Reached destination, stop everything and restart
REACHED_CONNECTION:Disconnect()
BLOCKED_CONNECTION:Disconnect()
WAYPOINTS = nil
NEXT_WAYPOINT_INDEX = nil
REACHED_CONNECTION = nil
BLOCKED_CONNECTION = nil
destination = nil
end
end)
end
NEXT_WAYPOINT_INDEX = 2
if (WAYPOINTS[NEXT_WAYPOINT_INDEX]) then
-- Go to first waypoint
if (WAYPOINTS[NEXT_WAYPOINT_INDEX].Action == Enum.PathWaypointAction.Jump) then
MONSTER_OBJ.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
-- Make sure the monster isn't stuck, out of the map, or on top of the map
if (MONSTER_OBJ.PrimaryPart.Position.Y >= 23) then
MoveToSpawn()
elseif (tick()-lastCheckStuck[1] > 3) then
if (lastCheckStuck[2]) then
local movedSince = (MONSTER_OBJ.PrimaryPart.Position-lastCheckStuck[2]).Magnitude
if (movedSince < 20) then
stuckCnt += 1
if (stuckCnt == 1) then
MONSTER_OBJ:PivotTo(MONSTER_OBJ.PrimaryPart.CFrame+Vector3.new(0, 0.3, 0))
elseif (stuckCnt == 3) then
stuckCnt = 0
MoveToSpawn()
end
end
end
lastCheckStuck = {tick(), MONSTER_OBJ.PrimaryPart.Position}
end
if (WAYPOINTS and NEXT_WAYPOINT_INDEX and WAYPOINTS[NEXT_WAYPOINT_INDEX] and humanoid) then
humanoid:MoveTo(WAYPOINTS[NEXT_WAYPOINT_INDEX].Position)
end
else
destination = nil
end
else
warn("Path not computed!", errorMessage)
destination = nil
end
FollowPath(destination)
else
-- Monster has a destination, just make sure it doesn't end up on top of the map, below the map, or stuck
if (MONSTER_OBJ.PrimaryPart.Position.Y <= 7) then
REACHED_CONNECTION:Disconnect()
BLOCKED_CONNECTION:Disconnect()
WAYPOINTS = nil
NEXT_WAYPOINT_INDEX = nil
REACHED_CONNECTION = nil
BLOCKED_CONNECTION = nil
MoveToSpawn()
elseif (MONSTER_OBJ.PrimaryPart.Position.Y >= 23) then
REACHED_CONNECTION:Disconnect()
BLOCKED_CONNECTION:Disconnect()
WAYPOINTS = nil
NEXT_WAYPOINT_INDEX = nil
REACHED_CONNECTION = nil
BLOCKED_CONNECTION = nil
MoveToSpawn()
elseif (tick()-lastCheckStuck[1] > 3 and lastCheckStuck[2]) then
local movedSince = (MONSTER_OBJ.PrimaryPart.Position-lastCheckStuck[2]).Magnitude
if (movedSince < 20) then
-- Monster is stuck, this is where I will move the monster up a stud, recalculate, or move to an open room
stuckCnt += 1
if (stuckCnt <= 2) then
MONSTER_OBJ:PivotTo(MONSTER_OBJ.PrimaryPart.CFrame+Vector3.new(0, 0.3, 0))
elseif (stuckCnt <= 4) then
REACHED_CONNECTION:Disconnect()
BLOCKED_CONNECTION:Disconnect()
REACHED_CONNECTION = nil
BLOCKED_CONNECTION = nil
WAYPOINTS = nil
elseif (stuckCnt == 5) then
stuckCnt = 0
REACHED_CONNECTION:Disconnect()
BLOCKED_CONNECTION:Disconnect()
REACHED_CONNECTION = nil
BLOCKED_CONNECTION = nil
NEXT_WAYPOINT_INDEX = nil
WAYPOINTS = nil
destination = nil
MoveToSpawn()
end
end
lastCheckStuck = {tick(), MONSTER_OBJ.PrimaryPart.Position}
end
task.wait()
FollowPath(destination)
end
end
Thanks for the help, let me know if you have any questions