So many debugs, no walking humanoid. Waypoints are successfully visualized every loop, but the humanoid doesn’t attempt to move at all, even though its WalkToPoint successfully replicates. No anchored parts, NetworkOwnership is fine, everything looks fine.
local PathfindingService = game:GetService("PathfindingService")
local function visualizeWaypoints(waypoints, cleanupList)
for _, waypoint in ipairs(waypoints) do
local part = Instance.new("Part")
part.Size = Vector3.new(0.5, 0.5, 0.5)
part.Position = waypoint.Position
part.Anchored = true
part.CanCollide = false
part.BrickColor = BrickColor.new("Bright green")
part.Parent = workspace
table.insert(cleanupList, part)
end
end
local function cleanupWaypoints(cleanupList)
for _, part in ipairs(cleanupList) do
part:Destroy()
end
end
local function ensureHumanoidCanMove(humanoid)
humanoid:ChangeState(Enum.HumanoidStateType.Running)
humanoid.PlatformStand = false
humanoid.Sit = false
end
local function finishWaypoints(redone, path, humanoid, character, cframe)
-- Ensure PrimaryPart exists
if not character.PrimaryPart then
warn("Character does not have a PrimaryPart.")
return
end
-- Ensure parts are not anchored
for _, part in ipairs(character:GetChildren()) do
if part:IsA("BasePart") and part.Anchored then
part.Anchored = false
print("Unanchored part:", part.Name)
end
end
-- Set network ownership to server
for _, part in ipairs(character:GetChildren()) do
if part:IsA("BasePart") then
part:SetNetworkOwner(nil)
end
end
-- Ensure the humanoid can move
ensureHumanoidCanMove(humanoid)
-- Compute the path
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, cframe.Position)
end)
if not success then
warn("Path computation failed: " .. errorMessage)
return
end
local waypoints = path:GetWaypoints()
local cleanupList = {}
if #waypoints == 0 then
warn("No waypoints generated.")
return
end
visualizeWaypoints(waypoints, cleanupList)
local function moveToWaypoints(waypoints)
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid.Jump = true
end
humanoid:MoveTo(waypoint.Position)
print("Moving to waypoint:", waypoint.Position)
local startTime = tick()
local predictedTime = (waypoint.Position - character.PrimaryPart.Position).Magnitude / humanoid.WalkSpeed
local timeout = predictedTime + 1 -- Adding a buffer to the predicted time
local arrived = false
local lastPosition = character.PrimaryPart.Position
while not arrived do
local distance = (waypoint.Position - character.PrimaryPart.Position).Magnitude
if distance < 1 then -- Small tolerance distance to consider arrival
arrived = true
elseif tick() - startTime > timeout then
print("Timeout reached. Recalculating path...")
cleanupWaypoints(cleanupList) -- Cleanup previous visualized waypoints
-- Recalculate path and visualize waypoints again
success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, cframe.Position)
end)
if not success then
warn("Path recomputation failed: " .. errorMessage)
return
end
waypoints = path:GetWaypoints()
if #waypoints == 0 then
warn("No waypoints generated after recomputation.")
return
end
visualizeWaypoints(waypoints, cleanupList)
moveToWaypoints(waypoints)
return
end
-- Ensure the humanoid can move
ensureHumanoidCanMove(humanoid)
-- Check if the humanoid has moved
if (character.PrimaryPart.Position - lastPosition).Magnitude > 0.1 then
print("Character is moving")
lastPosition = character.PrimaryPart.Position
else
print("Character is not moving")
end
task.wait(0.1)
end
end
cleanupWaypoints(cleanupList)
end
moveToWaypoints(waypoints)
end
moveEvents.OnServerInvoke = function(player,character,cframe)
local humanoid = character:FindFirstChild("Humanoid")
if humanoid then
-- pathfind to the position given
-- let the pathfind humanoid jump if it needs to (check distance between waypoints) (if it's too far, jump) (if it's too close, don't) (if it's in the way, jump)
-- if it's stuck, jump (check if it's been a certain amount of time since it moved)
local path = PathfindingService:CreatePath({WaypointSpacing = 2,AgentCanClimb = true})
finishWaypoints(false,path,humanoid,character,cframe)
-- face the humanoid in a certain direction
print("shouldnt be done yet")
task.wait(.25)
game:GetService("TweenService"):Create(character.PrimaryPart,TweenInfo.new(1,Enum.EasingStyle.Linear),{CFrame = CFrame.lookAlong(character.PrimaryPart.CFrame.Position,cframe.LookVector,Vector3.new(0,1,0))}):Play()
end
end
This next event successfully starts the function when hooked.
Changing the state of the humanoid by force doesn’t do anything, but it seems to walk towards the waypoint during GettingUp only.
local humanoid = character:FindFirstChild("Humanoid")
if humanoid then
-- pathfind to the position given
-- let the pathfind humanoid jump if it needs to (check distance between waypoints) (if it's too far, jump) (if it's too close, don't) (if it's in the way, jump)
-- if it's stuck, jump (check if it's been a certain amount of time since it moved)
local path = PathfindingService:CreatePath({WaypointSpacing = 2,AgentCanClimb = true})
finishWaypoints(false,path,humanoid,character,cframe)
-- face the humanoid in a certain direction
print("shouldnt be done yet")
task.wait(.25)
game:GetService("TweenService"):Create(character.PrimaryPart,TweenInfo.new(1,Enum.EasingStyle.Linear),{CFrame = CFrame.lookAlong(character.PrimaryPart.CFrame.Position,cframe.LookVector,Vector3.new(0,1,0))}):Play()
end
end
For extra context, I can select and rotate the character during gameplay from the server, and it enjoys moving towards the target while being airborne.