Currently, I am trying to make a PathFinding AI which sticks to a path, because it is frustrating when it finds the quickest route, not the most practical way. For example, the NPC jumping over railing instead of walking three more studs to walk up the said stairs.
After watching and mimicking a video that provided code for a raycasting and magnitude pathfinding (using the pathfinding service, because all of the open source A* pathfinding scripts are out of date), I made the following script that needs two parameters: The NPC’s name and the Goal point.
Then, I planned to use Collision groups to make invisible borders around the paths, so that the NPC stayed within the boundries.
WorkSpace = game:GetService("Workspace")
local func = {}
func.WalkTo = function(who,objective)
WorkSpace:WaitForChild(who):WaitForChild("HumanoidRootPart"):SetNetworkOwner(nil)
repeat wait()
local rootPart = WorkSpace:WaitForChild(who):WaitForChild("HumanoidRootPart")
local human = WorkSpace:WaitForChild(who):WaitForChild("Humanoid")
local function findTarget()
local dist = 200
local target = WorkSpace:WaitForChild("Nodes"):WaitForChild(objective)
return target
end
local goal = findTarget()
if goal then
local ray = Ray.new(rootPart.Position, (goal.Position - rootPart.Position).Unit * 200)
local hit,position = WorkSpace:FindPartOnRayWithIgnoreList(ray,{WorkSpace:WaitForChild(who)})
if hit then
if hit:IsDescendantOf(goal.Parent) then
human:MoveTo(goal.Position)
else
human:MoveTo(goal.Position)
wait()
local pathfindingService = game:GetService("PathfindingService")
local pathParams = {
AgentHeight = 5,
AgentRadius = 2,
AgentCanJump = false
}
local path = pathfindingService:CreatePath(pathParams)
local newpath = path:ComputeAsync(rootPart.Position,goal.Position)
local points = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for i,v in pairs (points) do
human:MoveTo(v.Position)
human.MoveToFinished:Wait()
if v.Action == Enum.PathWaypointAction.Jump then
human.Jump = true
end
if (points[#points].Position - goal.Position).magnitude > 15 then
break
end
end
else
warn("No Path Found")
break
--human:MoveTo(goal.Position)
end
end
end
end
until (WorkSpace:WaitForChild(who):WaitForChild("HumanoidRootPart").Position - WorkSpace:WaitForChild("Nodes"):WaitForChild(objective).Position).magnitude < 3
end
return func
But the problem is that it does not take heed of the invisible barriers, and instead tries to go straight towards the goal point:
But in the GIF below, you can see that it IS generating a path in a wider enviroment:
I’ve tried disabling the collision group script, tweaking values, etc. I’d hate to see that it’s impossible for Pathfinding Service to generate a path in a tight environment. If anyone could point me in the right direction it would be fantastic!
Place with scripts: PathfindingNew.rbxl (23.4 KB)