Godot 4.2中@tool脚本设置小行星属性遇索引无效错误求助
解决Godot 4.2 @tool模式小行星生成器变量设置错误问题
问题根源
在@tool模式下,编辑器实例化场景的流程和运行时不一样:运行时场景脚本会和节点同步加载初始化,但编辑器里节点创建后,脚本可能存在延迟加载/初始化的情况——你刚实例化小行星就直接设置size这类自定义变量时,RigidBody3D节点还没关联上你的自定义脚本,自然找不到这些变量,就会抛出错误。
具体修复方案
1. 给小行星脚本加上@tool支持
先把小行星根节点的脚本加上@tool注解,让编辑器能识别并初始化脚本里的自定义变量:
@tool extends RigidBody3D @export var size: float = 1.0 @export var noise_scale: float = 0.5 @export var noise_adjustment: float = 0.2 func _ready(): # 编辑器和运行时都执行生成逻辑 generate_asteroid_shape() func generate_asteroid_shape(): # 你的小行星形状生成代码 pass
2. 生成器脚本里等脚本初始化完再设变量
在生成器的@tool脚本中,不要实例化后立刻设置变量,改用await等待节点脚本加载完成,确保变量能被正确访问:
@tool extends Node3D @export var asteroid_scene: PackedScene func _ready(): if Engine.is_editor_hint(): spawn_asteroid_in_editor() func spawn_asteroid_in_editor(): var asteroid = asteroid_scene.instantiate() as RigidBody3D add_child(asteroid) # 等待节点脚本初始化完成 await asteroid.ready # 保险起见,再加一层判断确保脚本已加载 while not asteroid.script: await get_tree().process_frame # 现在可以安全设置变量 asteroid.size = 2.0 asteroid.noise_scale = 0.6 asteroid.noise_adjustment = 0.3 # 手动触发形状生成(编辑器下_ready可能已执行,重新调用确保更新) asteroid.generate_asteroid_shape()
3. 用setter触发形状更新(更稳妥)
把小行星的变量改成带setter的形式,这样不管是编辑器还是运行时,只要变量被修改,就自动触发形状更新,不用依赖_ready的执行时机:
@tool extends RigidBody3D var _size: float = 1.0 @export setget set_size, get_size var _noise_scale: float = 0.5 @export setget set_noise_scale, get_noise_scale var _noise_adjustment: float = 0.2 @export setget set_noise_adjustment, get_noise_adjustment func set_size(new_size: float): _size = new_size generate_asteroid_shape() func get_size() -> float: return _size # 同理实现noise_scale和noise_adjustment的setter/getter func generate_asteroid_shape(): # 你的小行星形状生成代码 pass func _ready(): generate_asteroid_shape()
这种方式下,编辑器会自动识别这些带setter的变量,修改时直接触发形状更新,完全适配@tool模式的编辑器预览需求。
4. 别用_process循环凑时机
之前把生成逻辑移到_process里没用,因为问题不在执行频率,而在脚本未初始化导致变量找不到,用上面的等待或setter方案才是根本解决办法。
内容的提问来源于stack exchange,提问作者Bagutreko
相关产品推荐
相关产品推荐

