Optimized A-STAR(A*) Pathfinding

Flying npcs will already have a flight height variable in npc which moves the npc up, some distance up from ground. And a function to check the distance to ground to reduce or boost the flight force.

So think them as seperate.

What i do is calculate the path from the ground below. And if there is obstacle in front of npc, because that your npc is not on the ground, you can get the height of the part and move the npc up or down with increasing/lowering the force, whichever fits your case.

You can do that with only 1 raycast to front that can run on average every .5 second. No haul at all. You can also check up direction to limit the flight height but flight height function already handles that so the trick is just moving them based on ground below with some front obstacle checks.

well I can tell you why nodes when you debug them on the size 3 and why its the best option I could do. Is because 5 or 4 (maybe) will always not find a solution around walls. so I just use 3 and not 0-2. That was in my code.

If you didn’t know. (I know the one you sent was yours but improved and working but just letting you know why)

What might be the issue in this case?

The target part is too high and since the path is 3d the next waypoint is at the same z and x position but higher Y so that makes the npc never reach the node because the node is above

node size doesnt really do a lot. its 3d grid so i should have made that one in the description

Okay, but just saying the size 3 only works for me.

Hello! First of all, thank you for sharing this module!

May I ask why you used Manhattan distance for the heuristic instead of Euclidean? I found that changing it to Euclidean made it faster because it is 3D area rather than 2D and grid based. (Things can move diagonally)

local function Heuristic(a, b)
	return (a - b).Magnitude
end

Also, as @AndiArbeitlol pointed out earlier, there seems to be timeouts occurring whenever I place the part in a specific area of the wall. You can replicate this by simply putting the part right about here:
image

I added a part in the script that visualizes the error for a better understanding of why the script timed out and this is what I got:
image
Hopefully this helps?

EDIT: Nevermind, after further testing, the timeout problem persists. It just happens less often.
I think I fixed the timeout problem. I just changed the value of the radius of the check in the AStar function to 1:

local function AStar(start, goal)
	start = roundToStep(start)
	goal = roundToStep(goal)
	local openSet = PriorityQueue.new()
	openSet:Push(start, 0)
	local cameFrom = {}
	local gScore = {[start] = 0}
	local fScore = {[start] = Heuristic(start, goal)}
	local inPart = #workspace:getPartBoundsInRadius(goal, 1, oOverlapParams) > 0 
    --^ this one

	if inPart then
		return
		
	end
	while not openSet:IsEmpty() do
		local current = openSet:Pop()

		if current == goal then
			local totalPath = {current}
			while cameFrom[current] do
				current = cameFrom[current]
				table.insert(totalPath, 1, current)
			end
			return totalPath
		end

		
		for _, neighbor in pairs(GetNeighbors(current)) do
			local tentative_gScore = gScore[current] + (neighbor - current).Magnitude
			if not gScore[neighbor] or tentative_gScore < gScore[neighbor] then
				cameFrom[neighbor] = current
				gScore[neighbor] = tentative_gScore
				fScore[neighbor] = gScore[neighbor] + Heuristic(neighbor, goal)
				openSet:Push(neighbor, fScore[neighbor])
			end
		end
	end

	return {}
end

The only noticeable limitation so far is that the NPC sometimes doesn’t move at all when the part is a bit too close to the wall.

The time out thing happens because the first and the last node should be checked if its InPart bounds. I forgot to put the goal and start node to be #workspace:getPartBoundsInRadius

Also i made another better working code. but still has issues

1 Like

Are you comfortable with sharing the new code, or will you wait until everything’s figured out to release it?

Again, thank you for sharing the module in the first place.

My new code is not really working on raycast for some reason. i will release when its working