|
|
|
|
Reply From: |
AlexTheRegent |
New rect_size will be available in next frame. I usually do it using next code:
func _ready():
for n in 3:
var child = child_control.instance()
print(child.rect_size)
child.size_flags_horizontal = SIZE_EXPAND_FILL
self.add_child(child)
yield(get_tree(), "idle_frame") # wait for next frame
print(get_children()[0].rect_size)
Or you can try to call queue_sort
on Container
, but I’m not sure if it will update sizes immediately.
Thanks for the answer!
However there are still some problems with this method:
In fact my code layout is something like:
var expanded_size
func _ready():
create_children()
print(get_children()[0].rect_size) #This printing is incorrect
print(expanded_size) #The printing is incorrect
func1() #cannot access expanded size in this method
func2() #cannot access expanded size in this method
func create_children():
for n in 3:
var child = child_control.instance()
print(child.rect_size)
child.size_flags_horizontal = SIZE_EXPAND_FILL
self.add_child(child)
yield(get_tree(), "idle_frame") # wait for next frame
print(get_children()[0].rect_size) #This printing is correct
expanded_size = get_children()[0].rect_size
There is still some wrong printings.
In fact I want to use the create_children() method to change some property of the object relating to the rect_size after expanding and THEN use it in func1() and func2().
lamkka | 2021-08-14 08:35
yield
works inside function where it was called, because this is one of the tools to work with asynchronous code. in this layout you need to add yield(get_tree(), "idle_frame")
after create_children()
too:
func _ready():
create_children()
yield(get_tree(), "idle_frame") # wait for next frame here too
print(get_children()[0].rect_size) #This printing is incorrect
print(expanded_size) #The printing is incorrect
func1() #cannot access expanded size in this method
func2() #cannot access expanded size in this method
here yield
acts as simple shorthand for (basically yield is shorthand for signals handlers):
# ...
get_tree().connect("idle_frame", self, "_on_idle_frame")
func _on_idle_frame():
print(get_children()[0].rect_size) #This printing is correct
expanded_size = get_children()[0].rect_size
if you will use it frequently, consider making wrapper around BoxContainer with custom signal, i.e. size_updated
to reduce amount of lines to write.
AlexTheRegent | 2021-08-14 10:02
Thank you very much!
That works! However, it seems to me it would be quite troublesome writing yield on every related function. Would you please also demonstrate how to
make wrapper around BoxContainer with custom signal, i.e. size_updated to reduce amount of lines to write?
Many thanks!
lamkka | 2021-08-14 10:32
It depends on your situation and overall layout. Why do you need to frequently change content of Container and why do you need to know exact size of new child?
AlexTheRegent | 2021-08-14 16:50
I would like to make an object - falling mechanism like those in any standard match - 3 game, e.g. candies falling in Candy Crush.
The container object is in fact a column that contains “candy” objects (child) which will disappear upon interaction; when a child disappear, a new “candy” OF THE SAME SIZE will fall into the column with suitable animation. That is why I need to frequently add and free children of the container.
Furthermore, the main thing is that the size of these child objects depend on the “capacity” of the container, which is a variable, while the container has fixed length. That is why I need to know the exact size of the expanded new child: the size of these objects under a fixed capacity is the expanded object size.
lamkka | 2021-08-15 03:16
It probably will be easier to solve your problem if you contact me in discord: AlexTheRegent#8015
Right now I’m think it will be easier for you to make your own Container
class rather than using existing BoxContainer
, because it was made for different cases.
AlexTheRegent | 2021-08-15 15:12