The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

+1 vote

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!

in Engine by (28 points)

1 Answer

+4 votes
Best answer

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)
by (28 points)
selected by

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
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.