So I was working with the pathfinding service and everything was going fine... until I realized that Path.Blocked apparently doesn't work correctly! As a result, I've been trying to find a way around this. I came up with a solution of maybe making lines through the waypoints and checking for a touched event or something? I'm not sure how I'd do that though. If you have any ideas I'm all ears!
Here is my code - it needs to create a new path if a part blocks the path....
--Pahfinding service local pathfinding = game:GetService("PathfindingService") --Settings for the path local obHorSep = 3 local obVerSep = 5 --Variables for storing the waypoints and the current waypoint index local waypoints local curWayIndex --Variables for npc, npc humanoid, the object, and the destination. local npc local npcHum local part local destination --Stores if the npc is moving local moving = false --Creates Path function createPath() --Creates the path type local path = pathfinding:CreatePath({AgentRadius=obHorSep,AgentHeight=obVerSep}) --Creates path between points path:ComputeAsync(npcHum.RootPart.Position,destination) path:ComputeAsync(npcHum.RootPart.Position,destination) --Checks if the path was successfully made if path.Status == Enum.PathStatus.Success then waypoints = path:GetWaypoints() --Gets waypoints --Sets the index to the start curWayIndex = 1 --Starts movement moving = true npcHum:MoveTo(waypoints[curWayIndex].Position) --After first movement, the moveToFinish will complete the rest else --Path was not successfully made end --Connects pathBlocked for if the path gets blocked path.Blocked:Connect(pathBlocked) local color = BrickColor.Random() for _, v in pairs(waypoints) do local ball = Instance.new("Part",workspace) ball.Size = Vector3.new(1,1,1) ball.BrickColor = color ball.Shape = Enum.PartType.Ball ball.Material = Enum.Material.Neon ball.Anchored = true ball.Position = v.Position ball.CanCollide = false end end --Sets values function setValues(npc1,part1) --Makes the values public npc = npc1 part = part1 --Finds npc humanoid for _,v in pairs(npc:GetDescendants()) do --Checks if descendant is humanoid if v:IsA("Humanoid") then --Sets the public npcHum value to the humanoid npcHum = v --Connects moveToFinish to npcHum so it reached next waypoint. npcHum.MoveToFinished:Connect(moveToFinish) break end end --Finds the destination depending on if it is a model or part if part:IsA("Model") then --If part is a model if part.PrimaryPart then --Check if it has a primary part destination = part.PrimaryPart.position else --if model doesn't have primary part --Set destination as the first part object in it. destination = part:FindFirstChildOfClass("Part").position end else --If the part isn't a model --Just set the destination to the part's position destination = part.Position end createPath() end --Runs if path gets blocked! function pathBlocked(blockIdx) print("Oh no! Blockage in the path!") --Checks if blockage is behind or ahead. if blockIdx > curWayIndex then --It is infront print("The blockage is infront, we need to make a new path!") --create a new path createPath() else --It is behind and nothing needs to happen print("Dont worry, the blockage is behind!") end end --Runs after the humanoid finishes moving to one waypoint function moveToFinish(reached) --Checks if npc has reached point and hasnt reached endpoint. if reached and curWayIndex < #waypoints then --Ups waypoint Index curWayIndex = curWayIndex+1 --Moves to next index npcHum:MoveTo(waypoints[curWayIndex].Position) elseif curWayIndex == #waypoints then moving = false print("Point Reached!") end end setValues(script.Parent,workspace.Test.PartSpecial)
Oh also I read about this... https://devforum.roblox.com/t/pathfindingservice-path-blocked-not-firing-why/278379 They seemed to have the same problem as me. There was a kind of solution at the end, but I'm not sure how I'd even do that!
I tried to change it to:
if path.Status == Enum.PathStatus.Success then waypoints = path:GetWaypoints() --Gets waypoints --Sets the index to the start curWayIndex = 1 --Starts movement moving = true --START CHECKING FOR VELOCITY CHANGE npcHum.RootPart:GetPropertyChangedSignal('Velocity'):Connect(velocityChanged) npcHum:MoveTo(waypoints[curWayIndex].Position) --After first movement, the moveToFinish will complete the rest else
adding this to it:
--START CHECKING FOR VELOCITY CHANGE npcHum.RootPart:GetPropertyChangedSignal('Velocity'):Connect(velocityChanged)
and then I added this function:
--Checks if velocity has gone below 0.1 (not moving) function velocityChanged() print("Changed") if(npcHum.RootPart.Velocity.magnitude < 0.1) then moving = false createPath() end end
Since if it did fire, it would create an infinite loop and moved the connection to here:
for _,v in pairs(npc:GetDescendants()) do --Checks if descendant is humanoid if v:IsA("Humanoid") then --Sets the public npcHum value to the humanoid npcHum = v --Connects moveToFinish to npcHum so it reached next waypoint. npcHum.MoveToFinished:Connect(moveToFinish) --START CHECKING FOR VELOCITY CHANGE npcHum.RootPart:GetPropertyChangedSignal('Velocity'):Connect(velocityChanged) break end end
But it still won't work?
I was reading at the end of the article, someone said to check the velocity. You can check it this way object.Velocity.magnitude
where object is the object that you want the velocity of. You can check if it is less than 0.1 and make a new path if so, quoted from the article.
Well, apparently a while loop works too :P - Not laggy
--Pahfinding service local pathfinding = game:GetService("PathfindingService") --Settings for the path local obHorSep = 3 local obVerSep = 5 --Variables for storing the waypoints and the current waypoint index local waypoints local curWayIndex --Variables for npc, npc humanoid, the object, and the destination. local npc local npcHum local part local destination --Stores if the npc is moving local moving = false local reachedDes = false --Creates the path type path = pathfinding:CreatePath({AgentRadius=obHorSep,AgentHeight=obVerSep}) --Creates Path function createPath() --Creates path between points path:ComputeAsync(npcHum.RootPart.Position,destination) path:ComputeAsync(npcHum.RootPart.Position,destination) --Checks if the path was successfully made if path.Status == Enum.PathStatus.Success then waypoints = path:GetWaypoints() --Gets waypoints --Sets the index to the start curWayIndex = 1 --Starts movement moving = true npcHum:MoveTo(waypoints[curWayIndex].Position) --After first movement, the moveToFinish will complete the rest else --Path was not successfully made end --Connects pathBlocked for if the path gets blocked path.Blocked:Connect(pathBlocked) local color = BrickColor.Random() end --Sets values function setValues(npc1,part1) --Makes the values public npc = npc1 part = part1 --Finds npc humanoid for _,v in pairs(npc:GetDescendants()) do --Checks if descendant is humanoid if v:IsA("Humanoid") then --Sets the public npcHum value to the humanoid npcHum = v --Connects moveToFinish to npcHum so it reached next waypoint. npcHum.MoveToFinished:Connect(moveToFinish) break end end --Finds the destination depending on if it is a model or part if part:IsA("Model") then --If part is a model if part.PrimaryPart then --Check if it has a primary part destination = part.PrimaryPart.position else --if model doesn't have primary part --Set destination as the first part object in it. destination = part:FindFirstChildOfClass("Part").position end else --If the part isn't a model --Just set the destination to the part's position destination = part.Position end createPath() end --Runs if path gets blocked! function pathBlocked(blockIdx) print("Oh no! Blockage in the path!") --Checks if blockage is behind or ahead. if blockIdx > curWayIndex then --It is infront print("The blockage is infront, we need to make a new path!") --create a new path createPath() else --It is behind and nothing needs to happen print("Dont worry, the blockage is behind!") end end --Runs after the humanoid finishes moving to one waypoint function moveToFinish(reached) --Checks if npc has reached point and hasnt reached endpoint. if reached and curWayIndex < #waypoints then --Ups waypoint Index curWayIndex = curWayIndex+1 --Moves to next index npcHum:MoveTo(waypoints[curWayIndex].Position) elseif curWayIndex == #waypoints then moving = false reachedDes = true print("Point Reached!") end end --Checks if velocity has gone below 0.1 (not moving) function velocityChanged() if(npcHum.RootPart.Velocity.Magnitude < 0.1) then moving = false createPath() end end while wait(1)do velocityChanged() if reachedDes then break end end setValues(script.Parent,workspace.Test.PartSpecial)