3d Astar Pathfinding without diagonal movement?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Pretzol

So, I watched a cool tutorial on Astar pathfinding in 3d, and once I implemented it into my game, I noticed that the unit would cut through corners on the gridmap often. I’m trying to get the unit to follow from point to point instead of going diagonally through them. Here’s a poorly drawn representation of the problem.

I was wondering if there was any way to stop connections between diagonal points? I’m hoping for it to only scan for points up, down, left, and right instead of top-left, top-right, etc. Here’s the part of the script where I think this is happening:

func _ready():
astar = AStar.new()
var cells = gridmap.get_used_cells()
for cell in cells:
	var ind = astar.get_available_point_id()
	astar.add_point(ind, gridmap.map_to_world(cell.x, cell.y, cell.z))
	all_points[v3_to_index(cell)] = ind
for cell in cells:
	for x in [-1, 0, 1]:
		for y in [-1, 0, 1]:
			for z in [-1, 0, 1]:
				var v3 = Vector3(x, y, z)
				if v3 == Vector3(0, 0, 0):
					continue
				if v3_to_index(v3 + cell) in all_points:
					var ind1 = all_points[v3_to_index(cell)]
					var ind2 = all_points[v3_to_index(cell + v3)]
					if !astar.are_points_connected(ind1, ind2):
						astar.connect_points(ind1, ind2, true)

Any help would be greatly appreciated!

:bust_in_silhouette: Reply From: Pretzol

Found a solution!
I played around with it until it started working, but then it would only do right turns on some turns and not others, so I added an if statement to stop a connection if it was a diagonal.

Here’s the code if anyone is using the tutorial and wants more grid-like movement.

func _ready():
astar = AStar.new()
var cells = gridmap.get_used_cells()
for cell in cells:
	var ind = astar.get_available_point_id()
	astar.add_point(ind, gridmap.map_to_world(cell.x, cell.y, cell.z))
	all_points[v3_to_index(cell)] = ind
for cell in cells:
	for x in [0, 1]:
		for y in [-1, 0, 1]:
			for z in [0, -1]:
				var v3 = Vector3(x, y, z)
				if v3 == Vector3(0, 0, 0):
					continue
				if v3 == Vector3(1, y, -1):
					continue
				print(cell, " ", (cell + v3), " v3: ", v3)
				if v3_to_index(v3 + cell) in all_points:
					var ind1 = all_points[v3_to_index(cell)]
					var ind2 = all_points[v3_to_index(cell + v3)]
					if !astar.are_points_connected(ind1, ind2):
						astar.connect_points(ind1, ind2, true)

Your code only checks one case, where the diagonal is to the right and north of the player.

if v3 == Vector3(1, y, -1):
     continue
if v3 == Vector3(-1, y, 1):
     continue
if v3 == Vector3(-1, y, -1):
    continue
if v3 == Vector3(1, y, 1):
    continue

AI | 2021-10-20 23:17