Godot: Children of GridContainer have same position as parent

Created on 27 Jun 2019  路  3Comments  路  Source: godotengine/godot

Godot version:
Tested in 3.1 and 3.1.1

Issue description:

I'm using a GridContainer to arrange nodes in a grid. However, I want to get the world/global position of each child in that container. When I try to do that with get_global_position() I only get the position of their parent node i.e. the container.

The children of the container are TextureRects. TextureRect doesn't have a global_position or position property. You can access rect_position or rect_global_position from Control (which it inherits from), but as I mentioned, that only gives the position/global_position of the parent (i.e. GridContainer), not the position of the TextureRect itself.

I print out the rect_global_position of all children in the GridContainer node and it only gives the position of the GridContainer i.e. (50, 50). This is despite the fact that I can see the TextureRects are actually placed in a grid. I also tried printing rect_position, which just comes out as (0, 0) for all children.

What's really weird about this is if I inspect the nodes during runtime with the remote debug scene the actual values for those nodes' positions are correct.

Can I extract the global position for each child in a GridContainer? Could this be a bug, or am I just misunderstanding how Control and Container nodes work?

The scene tree is:

  • Control (scene root)

    • GridContainer

    • TextureRect00

    • ...

    • TextureRect33

Minimal reproduction project:
Control_Container_Bug.zip

documentation enhancement

Most helpful comment

Is this documented anywhere?

I don't know, honestly. it doesn't seems so. I'll add the documentation tag

All 3 comments

Could this be a bug, or am I just misunderstanding how Control and Container nodes work?

Layouts update at the end of the frame. You are adding children and immediately checking their position, if you check that in the next frame it works:

func _ready():
    var puzzle = [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
    var size = 4
    set_columns(size)
    var x_region_size = 2
    var y_region_size = 2
    for row_num in range(0, size):
        for col_num in range(0, size):
            var texture_frame = TextureRect.new()
            texture_frame.set_texture(sprite_numbers[puzzle[row_num][col_num]])
            var cell_name = '{x}{y}'.format({"x": col_num, "y": row_num})
            texture_frame.set_name(cell_name)
            add_child(texture_frame)

    self.rect_global_position = Vector2(50, 50)
    call_deferred("test") # !!!!! Call test function on next frame.

func test():
    for child in self.get_children():
        printt(self, " found child: ", child)
        printt(rect_global_position)
        printt(child.rect_global_position)
        printt(child.anchor_left, child.anchor_right, child.anchor_top, child.anchor_bottom)
        print(child.margin_left, child.margin_right, child.margin_top, child.margin_bottom)

Layouts update at the end of the frame. You are adding children and immediately checking their position, if you check that in the next frame it works

Ohhh... thanks for that. I was so confused.

Is this documented anywhere?

Is this documented anywhere?

I don't know, honestly. it doesn't seems so. I'll add the documentation tag

Was this page helpful?
0 / 5 - 0 ratings