如何获取GridContainer子节点尺寸?运行时尺寸值为0的问题
解决GridContainer子节点运行时尺寸获取为0的问题
核心问题原因
GridContainer的布局计算是在节点_ready执行后的帧周期内完成的,再加上你是运行时动态设置NinePatchRect纹理,纹理加载完成的时机也会影响尺寸计算。仅用一次空闲帧等待,可能赶不上布局完成或纹理加载的节点,导致获取到的尺寸还是(0,0)。
具体解决方案
1. 监听节点resized信号(最可靠的方式)
GridContainer及子节点完成布局后都会触发resized信号,这是获取真实尺寸的最佳时机:
# 在外层NinePatchRect所在脚本中 func _ready(): $OuterNinePatchRect.connect("resized", self, "_on_outer_resized") # 动态加载纹理时,先等待纹理加载完成 var outer_texture = load("res://path/to/outer_nine_patch.tres") await outer_texture.loaded $OuterNinePatchRect.texture = outer_texture func _on_outer_resized(): # 用get_visible_rect()获取实际显示尺寸,比直接取size更准确 var outer_real_size = $OuterNinePatchRect.get_visible_rect().size # 内层NinePatchRect需要减去外层的边框留白 var inner_target_size = Vector2( outer_real_size.x - $OuterNinePatchRect.margin_left - $OuterNinePatchRect.margin_right, outer_real_size.y - $OuterNinePatchRect.margin_top - $OuterNinePatchRect.margin_bottom ) $InnerNinePatchRect.rect_size = inner_target_size
2. RichTextLabel的特殊处理
RichTextLabel的尺寸计算依赖文本渲染,除了监听resized,还要配合text_changed信号确保文本加载完成:
func _ready(): $RichTextLabel.connect("text_changed", self, "_on_label_text_updated") func _on_label_text_updated(): # 等待一帧让文本渲染完成 await get_tree().idle_frame var label_real_size = $RichTextLabel.get_visible_rect().size # 后续尺寸相关逻辑
3. 锚点与POSITION模式的适配
你设置内层NinePatchRect为layout_mode=POSITION是正确的,锚点会让尺寸受父容器约束,无法手动修改。只要在外层尺寸确定后,直接给内层设置rect_size即可,无需调整锚点。
为什么之前的空闲帧方案失效?
大概率是只等待了一次空闲帧,但此时纹理还未加载完成,或GridContainer的布局还未触发重新计算。需要先确保资源加载完成,再等待布局完成,或直接用resized信号触发,这比固定等待帧更可靠。
内容的提问来源于stack exchange,提问作者DotFX
相关产品推荐
相关产品推荐

