• 2D
  • How to make a grid of intractable objects?

In my game I want there to be a grid of objects that the player can interact with. I assume I'll need some sort of array to store data for each tile in the grid but I don't know how to handle something like this in Godot

You could tag the objects' nodes themselves as interactable (place them in a group, give them a property, whatever), and then place them where you want. You don't really need to store the data for the tiles in a grid.

You could perhaps use Godot's tilemapper if you want the objects to be evenly spaced between one another. Another solution is to make your own grid; put the objects you'd like to organize under a parent node; next, the parent node will have a script that decides where the child objects need to be placed and where, depending on how many columns you should have, and how far apart each object should be horizontally and vertically. The algorithm works like this:

obj_position = Vector2(parent_x + horizontal_space * (index % columns), parent_y + vertical_space * floor(index / columns))

You can switch things around if you'd rather objects be ordered along rows instead of columns. Each object would probably need its own script for the interactability, though it's hard to say how that would happen without more information. Is this for UI? Is this something the player avatar interacts with? In any case that's the gist of it.

@Somnivore said: You could perhaps use Godot's tilemapper if you want the objects to be evenly spaced between one another. Another solution is to make your own grid; put the objects you'd like to organize under a parent node; next, the parent node will have a script that decides where the child objects need to be placed and where, depending on how many columns you should have, and how far apart each object should be horizontally and vertically. The algorithm works like this:

obj_position = Vector2(parent_x + horizontal_space * (index % columns), parent_y + vertical_space * floor(index / columns))

You can switch things around if you'd rather objects be ordered along rows instead of columns. Each object would probably need its own script for the interactability, though it's hard to say how that would happen without more information. Is this for UI? Is this something the player avatar interacts with? In any case that's the gist of it.

This is basically exactly what I was looking for, thank you! My only question now is how do I actually change the child's position in the script? The code you gave makes sense, I just don't know how to implement it

@rimbley2032 said: This is basically exactly what I was looking for, thank you! My only question now is how do I actually change the child's position in the script? The code you gave makes sense, I just don't know how to implement it

Enter your for-loop so you can modify each child in turn, in the ready callback so it happens immediately once the parent comes into play:

    export(int) var horizontal_space = 32 #change these in editor to get desired effect
    export(int) var columns = 3
    func _ready():
        var children = get_children() #children is a generic array
        for i in range(children.size()): #size() tells us how many children to iterate through
            var child = children[i] #get a reference to the child at i's index
            child.position = Vector2(horizontal_space * (i % columns), vertical_space * floor(i / columns)) #child's position is accessed with its position member variable

You would forego adding the parent's position here since being children of the parent, it always takes the parent's position into account. However if you weren't using a parent/children setup, you might want to consider using global_position instead.