Pathfinding Broken

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.

3 Likes

I found more valuable information to solve the issue, but the problem isn’t fixed. The humanoid’s state isn’t doing something right, but not sure why at all.

2 Likes