I am new to scripting LUA and Roblox. I decided to learn basic mechanics and here is my attempt to understand basic pathfinding.
I took basic code from here:
And decided to try and scale it up. I added height so that the zombies would need to jump, a falling terrain object to block paths and multiple destinations.
The script seems to work ok for a short while but quickly you see that zombies stop pathing and have incredible lag. No errors just a pause.
What am I doing wrong?
I have thought of swapping to a simpler design such as the one posted by Little_Joes here: Problem With Pathfinding Service - #3 by HEMAN_9
But If I just copied answers I don’t learn and there is something to be learned through this failure.
Attached is my script.
See:
- ReplicatedStorage.Zombie.pathfinding
- ServerScriptService.Spawner
Pathfinding.rbxl (37.7 KB)
ServerScriptService.Spawner
local ZOMBIE_COUNT = 10
local Players = game:GetService(“Players”)
while #Players:GetPlayers() < 1 do
Players.PlayerAdded:Wait()
end
for i=1, ZOMBIE_COUNT, 1 do
local delay = math.random(1,100)*.03
print("Spawning zombie"..i.." then waiting "..delay)
local zombie = game.ReplicatedStorage.Zombie:Clone()
zombie.Parent = game.Workspace
zombie.Name = zombie.Name..i
zombie.Zombie.WalkSpeed = 64
wait(delay)
end
ReplicatedStorage.Zombie.pathfinding
local SHOW_WAYPOINTS = true
local Players = game:GetService("Players")
while #Players:GetPlayers() < 1 do
Players.PlayerAdded:Wait()
end
script.Parent:WaitForChild("HumanoidRootPart")
game.Workspace:WaitForChild("PathDestinations")
local zombie = script.Parent
local humanoid = zombie.Zombie
local destinations = game.Workspace.PathDestinations:GetChildren()
local destinationIndex = math.random(1,#destinations)
local PathfindingService = game:GetService("PathfindingService")
local path = PathfindingService:CreatePath()
local waypoints
local currentWaypointIndex
-- Just for troubleshooting
local moveToCalls = 0
local onWaypointReachedCalls = 0
local function showWaypointPath(waypoints)
for i, waypoint in pairs(waypoints) do
local part = Instance.new("Part")
part.Shape = "Ball"
part.Material = "Neon"
part.Size = Vector3.new(0.6, 0.6, 0.6)
part.Position = waypoint.Position
part.Anchored = true
part.CanCollide = false
part.Parent = script.parent.Path
part.Name = "path_"..i
end
end
local function deleteWaypointPath()
for _, wp in ipairs(script.parent.Path:GetChildren()) do
wp:Destroy()
end
end
local function getNewDestination()
local potentialDestination
repeat
potentialDestination = math.random(1,#destinations)
until potentialDestination ~= destinationIndex
return potentialDestination
end
local function walkToNextWaypoint()
currentWaypointIndex = currentWaypointIndex + 1
--print( "Moving "..zombie.Name.." to waypoint "..currentWaypointIndex.."/"..#waypoints.." on way to "..destinations[destinationIndex].Name.." moveToCalls: "..moveToCalls.." onWaypointReachedCalls: "..onWaypointReachedCalls)
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
--humanoid.Jump = true
end
moveToCalls = moveToCalls + 1
humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
end
local function startWalkingToDestination()
currentWaypointIndex = 0
walkToNextWaypoint()
end
local function stopWalking()
if SHOW_WAYPOINTS then
deleteWaypointPath()
end
humanoid:MoveTo(zombie.HumanoidRootPart.Position)
end
local function createNewPath()
path:ComputeAsync(zombie.HumanoidRootPart.Position, destinations[destinationIndex].Position)
if path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
if SHOW_WAYPOINTS then
showWaypointPath(waypoints)
end
startWalkingToDestination()
else
print(zombie.Name.." path not found to ".. destinations[destinationIndex].Name.." moveToCalls: "..moveToCalls.." onWaypointReachedCalls: "..onWaypointReachedCalls)
stopWalking()
end
end
local function onPathBlocked(blockedWaypointIndex)
print(zombie.Name.." is BLOCKED at index "..blockedWaypointIndex.." trying to reach destination "..destinations[destinationIndex].Name.." moveToCalls: "..moveToCalls.." onWaypointReachedCalls: "..onWaypointReachedCalls)
if blockedWaypointIndex > currentWaypointIndex then
createNewPath()
end
end
local function onWaypointReached(reached)
onWaypointReachedCalls = onWaypointReachedCalls + 1
if reached and waypoints and currentWaypointIndex < #waypoints then
walkToNextWaypoint()
elseif waypoints and currentWaypointIndex == #waypoints then
if SHOW_WAYPOINTS then
deleteWaypointPath()
end
print(zombie.Name.." reached the destination "..destinations[destinationIndex].Name.." moveToCalls: "..moveToCalls.." onWaypointReachedCalls: "..onWaypointReachedCalls)
destinationIndex = getNewDestination()
print("New destination for "..zombie.Name.." "..destinations[destinationIndex].Name.." moveToCalls: "..moveToCalls.." onWaypointReachedCalls: "..onWaypointReachedCalls)
createNewPath()
else
print(zombie.Name.." hasn't reached the destination "..destinations[destinationIndex].Name.." moveToCalls: "..moveToCalls.." onWaypointReachedCalls: "..onWaypointReachedCalls)
createNewPath()
end
end
humanoid.MoveToFinished:Connect(onWaypointReached)
path.Blocked:Connect(onPathBlocked)
createNewPath()