Hello, I’m trying to make a monster however there are a few issues.
- The monster runs into walls often even though a pathModifier has been set so the monster can go through doors
- The monster movement is very figity and the monster will sometimes walk in the wrong direction for a few seconds before correcting its movement
As you can see here, I have this “house” with a path modifier showing the door:
The monster is always given the position of the player and should walk through the door but instead does this:

Example of monster movement:
Here is my code:
local Rig = script.Parent
local Humanoid = Rig:WaitForChild("Humanoid")
local Root = Rig.HumanoidRootPart
local Idle = Humanoid.Idle
local Crawl = Humanoid.Crawl
local Animator = Humanoid:WaitForChild("Animator")
local IdleAnimation = Animator:LoadAnimation(Idle)
local CrawlAnimation = Animator:LoadAnimation(Crawl)
local PathfindingService = game:GetService("PathfindingService")
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
function goToLocation(location)
local path = PathfindingService:CreatePath()
local success,failure = pcall(function()
path:ComputeAsync(location, Root.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
goToLocation(location)
end
end)
if not reachedConnection then
reachedConnection = Humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
print('k')
CrawlAnimation.Looped = false
CrawlAnimation:Stop()
end
end)
end
nextWaypointIndex = 2
CrawlAnimation.Looped = true
CrawlAnimation:Play()
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", failure)
end
end
task.wait(3)
print("starting")
while true do
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
print("w")
task.wait(1)
end
Here is how the monster is made:

you will need to add this to your code
local path = PathfindingService:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
Costs = {
LabelText = math.huge()
}
}
Inside the Costs table you need to add the Label attribute of the PathfindingModifier with it equaling math.huge() EG:
Costs = {
LabelText = math.huge()
}
This will stop the monster running into anything with this pathfinding modifier
Okay I tried doing
local path = PathfindingService:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
Costs = {
ThisText = 100
}
})
```
and this was the result
Instead of having a While true loop, instead when the path ends then call the function again, because you are making too many paths the movement will jitter as its calculating the next path
Also create the path variable at the start of the script as shown below:
local Rig = script.Parent
local Humanoid = Rig:WaitForChild("Humanoid")
local Root = Rig.HumanoidRootPart
local Idle = Humanoid.Idle
local Crawl = Humanoid.Crawl
local Animator = Humanoid:WaitForChild("Animator")
local IdleAnimation = Animator:LoadAnimation(Idle)
local CrawlAnimation = Animator:LoadAnimation(Crawl)
local PathfindingService = game:GetService("PathfindingService")
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local path = PathfindingService:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
Costs = {
ThisText = 100
}
})
Then just call the ComputeAsync function on the path variable
Okay I put the path outside
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local path = PathfindingService:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
Costs = {
ThisText = 100
}
})
function goToLocation(location)
and I got rid of the while loop and repeated the function when it ended:
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
CrawlAnimation.Looped = false
CrawlAnimation:Stop()
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
end
here is the result:
I believe its because the NPC had 2 paths running at the same time, so it walked to a waypoint on one path, but then went to another waypoint from another path.
If this is the case, this sanity check might help
Add a variable at the start of the script called
TickTime
Add a local variable inside the goToLocation() function called
CurrentTime
Update both variables to the os.time() when goToLocation() called
Then before you call the function:
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
create an if statement to check whether CurrentTime and TickTime are the same.
If they are then use the MoveTo function, and if not then dont do anything
what if instead of doing all that I just did a debounce?
local debounce = false
local function printHello()
if debounce == false then
debounce = true
print("Hello")
task.wait(0.5)
debounce = false
else
print("already going")
end
end
printHello() -- "Hello"
printHello() -- "already going"
its still doing this
Here are my thoughts…
- Why does it go back to its starting location?
- Why does it stop moving when its not in a while loop?
here is the full script:
local Rig = script.Parent
local Humanoid = Rig:WaitForChild("Humanoid")
local Root = Rig.HumanoidRootPart
local Idle = Humanoid.Idle
local Crawl = Humanoid.Crawl
local Animator = Humanoid:WaitForChild("Animator")
local IdleAnimation = Animator:LoadAnimation(Idle)
local CrawlAnimation = Animator:LoadAnimation(Crawl)
local PathfindingService = game:GetService("PathfindingService")
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local debounce = false
local path = PathfindingService:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
Costs = {
ThisText = 100
}
})
function goToLocation(location)
if debounce == false then
debounce = true
local success,failure = pcall(function()
path:ComputeAsync(location, Root.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
goToLocation(location)
end
end)
if not reachedConnection then
reachedConnection = Humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
CrawlAnimation.Looped = false
CrawlAnimation:Stop()
debounce = false
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
end
end)
end
nextWaypointIndex = 2
CrawlAnimation.Looped = true
CrawlAnimation:Play()
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", failure)
end
end
end
task.wait(3)
print("starting")
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
try to remove the if not reachedConnection then and just create the new connection whenever a path is calculated
also forgot debounce = false in the path.Blocked function
this worked however for some reason it keeps walking back to its starting point
here is the current script:
local Rig = script.Parent
local Humanoid = Rig:WaitForChild("Humanoid")
local Root = Rig.HumanoidRootPart
local Idle = Humanoid.Idle
local Crawl = Humanoid.Crawl
local Animator = Humanoid:WaitForChild("Animator")
local IdleAnimation = Animator:LoadAnimation(Idle)
local CrawlAnimation = Animator:LoadAnimation(Crawl)
local PathfindingService = game:GetService("PathfindingService")
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local debounce = false
local path = PathfindingService:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = false,
Costs = {
ThisText = 100
}
})
function goToLocation(location)
if debounce == false then
debounce = true
local success,failure = pcall(function()
path:ComputeAsync(location, Root.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
debounce = false
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
end
end)
reachedConnection = Humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
CrawlAnimation.Looped = false
CrawlAnimation:Stop()
debounce = false
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
end
end)
nextWaypointIndex = 2
CrawlAnimation.Looped = true
CrawlAnimation:Play()
Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", failure)
end
end
end
task.wait(6)
print("starting")
goToLocation(game.Players.KrimsonWoIf.Character.HumanoidRootPart.Position)
you have put the arguments of the ComputeAsync the wrong way around