You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot 4.2.1实例化场景后调用set_texture报错:节点属性为Null

问题描述

我有一个继承自Area2D的场景DragonSelector,场景内包含名为DragonSprite的Sprite2D节点,相关代码如下:

DragonSelector.gd

class_name DragonSelector
extends Area2D

@onready var dragon_sprite = $DragonSprite

func _ready():
    pass 

func _process(delta):
    pass

func set_texture(dragon_texture: Texture):
    dragon_sprite.Texture = dragon_texture

我在Main场景中实例化该场景并尝试运行时设置纹理,代码如下:
Main.gd

class_name Main
extends Node2D

var dragon_selector_scene = preload("res://dragon_selector/dragon_selector.tscn")

func _ready():
    var dragon_selector_instance = dragon_selector_scene.instantiate()
    var texture = preload("res://dragon/flying_dragon-gold.png")
    dragon_selector_instance.set_texture(texture)
    add_child(dragon_selector_instance)
    dragon_selector_instance.position = Vector2(100, 100) 
    
func _process(delta):
    pass

运行后触发错误:Invalid set index 'Texture' (on base: 'Nil') with value of type 'CompressedTexture2D',错误定位到set_texture方法中的纹理赋值行。

为验证纹理路径正确,我修改了DragonSelector.gd的set_texture方法,直接在方法内加载纹理,修改后运行正常:

func set_texture(dragon_texture: Texture):
    dragon_sprite.Texture = preload("res://dragon/flying_dragon-gold.png")
    #dragon_sprite.Texture = dragon_texture

使用Godot 4.2.1版本,寻求问题的修正方案。


修正方案

问题根源

@onready修饰的变量要等到节点被添加到场景树后才会完成初始化。你当前的代码是先调用set_texture,再执行add_child,此时dragon_selector_instance还未进入场景树,dragon_sprite处于Nil状态,因此赋值操作会报错。而直接在set_texture内预加载纹理时,实际执行赋值的时机可能已经触发了@onready(节点已入树),所以能正常运行。

另外注意:Godot 4中节点属性采用小写驼峰命名,Texture应改为texture,这是容易忽略的规范问题。

可行解决方式

方式一:调整调用顺序,先添加节点再设置纹理

修改Main.gd的_ready方法,先将实例添加到场景树,再调用set_texture:

func _ready():
    var dragon_selector_instance = dragon_selector_scene.instantiate()
    var texture = preload("res://dragon/flying_dragon-gold.png")
    add_child(dragon_selector_instance) # 先加入场景树,触发@onready初始化
    dragon_selector_instance.set_texture(texture) # 再设置纹理
    dragon_selector_instance.position = Vector2(100, 100) 

方式二:手动初始化节点引用,不依赖@onready

如果需要在节点入树前设置纹理,可以修改DragonSelector.gd,手动确保dragon_sprite不为Nil:

class_name DragonSelector
extends Area2D

var dragon_sprite: Sprite2D

func _ready():
    dragon_sprite = $DragonSprite

func set_texture(dragon_texture: Texture):
    # 若未初始化,手动获取节点
    if not dragon_sprite:
        dragon_sprite = $DragonSprite
    dragon_sprite.texture = dragon_texture # 改用小写texture

内容的提问来源于stack exchange,提问作者Yoav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:15:17