I created a path finding a using the documentation this and it works pretty well… trusses. it just acts strange around them getting stuck in a loop or outright refusing to climb them. This is a problem as the script is meant to be for a zombie rush game where large a quantity of zombies are traversing a complex map.
The code. it’s used inside a server Script inside a dummy.
local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
local path = PathfindingService:CreatePath({
AgentRadius = 1.5,
AgentHeight = 5,
AgentCanJump = true,
AgentCanClimb = true,
WaypointSpacing = 6,
Costs = {
Climb = 10, -- Cost of the climbing path; default is 1
Jump = 50
}
})
local character = script.Parent
local rootPart = character:WaitForChild("HumanoidRootPart")
rootPart:SetNetworkOwner(nil)
local humanoid = character:WaitForChild("Humanoid")
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local climbingTruss = false
rootPart.Touched:Connect(function(obj)
if obj:IsA("TrussPart") then
climbingTruss = true
else
climbingTruss = false
end
end)
local function followPath(destination)
-- Compute the path
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- Get the path waypoints
waypoints = path:GetWaypoints()
-- Detect if path becomes blocked
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- Check if the obstacle is further down the path
if blockedWaypointIndex >= nextWaypointIndex then
-- Stop detecting path blockage until path is re-computed
blockedConnection:Disconnect()
-- Call function to re-compute new path
followPath(destination)
end
end)
-- Detect when movement to next waypoint is complete
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
-- Increase waypoint index and move to next waypoint
if waypoints[nextWaypointIndex+1].Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
print("jumped")
end
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
end
end)
end
-- Initially move to second waypoint (first waypoint is path start; skip it)
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
function getNearestCharacter()
local nearestCharacter, nearestDistance
for _, player in pairs(game:GetService("Players"):GetPlayers()) do
local character = player.Character
local distance = player:DistanceFromCharacter(rootPart.Position)
if not character or
distance > 512 or
(nearestDistance and distance >= nearestDistance)
then
continue
end
nearestDistance = distance
nearestCharacter = character
end
return nearestCharacter
end
while true do
if blockedConnection then
blockedConnection:Disconnect()
end
local player = getNearestCharacter()
if player then
if climbingTruss == false then
if (rootPart.Position - player.HumanoidRootPart.Position).magnitude < 12 then
humanoid:MoveTo(player.HumanoidRootPart.Position)
task.wait(.1)
else
followPath(player.HumanoidRootPart.Position)
end
else
humanoid:MoveTo(player.HumanoidRootPart.Position)
end
end
task.wait(.1)
end
How do I improve upon this without having to write path finding using A*?