0 votes

Hello Godot Experts,

I am trying to use an AStar system to control ai in my game. I have managed to get this working for one sprite but since the AStar scripts are attached to the tilemap and the sprite is a child of that, when I try to add multiple sprites the script only moves the first one as it is called Player, and the others are Player2, Player3, etc.

Image Reference (Background is the one that holds the AStar scripts)

Is there any way I could access all children from the tilemap script and make them move too, without having to instance the tilemap as a child of the Player?

If any further information is required, please ask. Thank you

Godot version 3.2.3.stable
in Engine by (25 points)

1 Answer

+1 vote
Best answer

As the AStar node is implemented through the TileMap it can be responsible for path-finding any child or sibling node. Children of the TileMap have their position property in local space meaning it takes the TileMap's origin into account.

Assuming the TileMap's parent is positioned at (0,0), if your TileMap has its origin at (64,64), the formula for finding a child's global position would be child_node.position + Vector2(64,64) *this is also calculated for you via the child_node.global_position property. However, a sibling of the TileMap at the exact same position would have its sibling_node.position == sibling_node.global_position because its parent (same as TileMap's) has its origin at (0,0).

At some point in your code you have a function that takes in two positions and returns a path between them. I don't know how you have your AStar node implemented but seeing as you're using a TileMap you're probably feeding it map coordinates. So your function looks something like this:

func find_path(world_start, world_end)
    var map_start = world_to_map(world_start)
    var map_end = world_to_map(world_end)
    var start_point_index = get_point_index(map_start)
    var end_point_index = get_point_index(map_end)

    var map_path = astar_node.get_point_path(start_point_index, end_point_index)
    var world_path = []
    for map_point in map_path:
         world_path.append(map_to_world(map_point.x, map_point.y))

    return world_path

The trick of it is to always call this function with the same kind of coordinates. Either coordinates that local to the TileMap, doing the conversion before you call the function - as in the example above - or global coordinates and take that into account when you're calling it. TileMap.get_used_rect().position gets you the origin for your TileMap if you decide to go the global route.

by (3,710 points)
selected by
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.