Godot报错Invalid set index 'weapon' (on base: 'Spatial')
问题报错
Invalid set index 'weapon' (on base: 'Spatial') with value of type 'Spatial (weapon_manager.gd)'.
问题根因
代码存在4个核心问题,直接触发该报错及后续逻辑异常:
- 给武器节点赋值自定义属性时,目标节点未挂载对应武器脚本/未提前声明对应属性,Godot不允许给原生
Spatial类型节点动态添加未定义的属性 - 代码存在严重缩进错误,
change_weapon函数中武器非空时的切枪逻辑全被错误放在if weapons[new_weapon_slot] == null判断块内,return语句后所有切枪逻辑永远不会执行 - 存在多处变量名/对象调用错误:同一切枪判断分支中误对字符串类型的
current_weapon_slot调用武器方法,属性赋值时疑似存在变量名拼写偏差(代码中写的是weapon_manager,报错提示尝试赋值的属性是weapon) - 资源预加载类型不统一:
all_weapons字典中Pistol_A加载的是.gd脚本文件,其余两个武器加载的是.tscn场景文件,后续实例化时会触发类型不匹配问题
修复步骤
- 补全所有武器脚本的属性声明
找到场景树中$Unarmed、$Pistol_A、$Rifle_A三个武器节点挂载的脚本,在每个脚本顶部提前声明需要外部赋值的变量,避免动态赋值报错:
全局搜索代码,确认所有给武器节点赋值extends Spatial # 新增以下两个变量声明,变量名和weapon_manager里赋值的名字保持完全一致 var weapon_manager var playerweapon_manager的位置没有拼写成weapon,和脚本内声明的变量名完全匹配。 - 修正
change_weapon函数的缩进和逻辑错误
把return语句之后的切枪逻辑全部向前缩进一级,放到if weapons[new_weapon_slot] == null判断块外部,同时修正错误的方法调用对象,修正后的函数代码如下:func change_weapon(new_weapon_slot): if new_weapon_slot == current_weapon_slot: # 原代码错误调用了字符串变量的方法,改为当前武器对象 current_weapon.update_ammo() return if weapons[new_weapon_slot] == null: return # 以下代码原来缩进错误,全部移到if判断外 current_weapon_slot = new_weapon_slot changing_weapon = true weapons[current_weapon_slot].update_ammo() # 切换武器 if current_weapon != null: unequipped_weapon = false current_weapon.unequip() set_process(true) - 统一
all_weapons的资源加载类型
把Pistol_A的预加载路径改为对应的.tscn场景文件,和其余两个武器保持一致,避免后续实例化时类型错误:all_weapons = { "Unarmed" : preload("res://Unarmed.tscn"), # 原代码这里加载的是gd脚本,改为对应手枪场景 "Pistol_A" : preload("res://pistol_a/pistol_a.tscn"), "Rifle_A" : preload("res://rifle_a/rifle_a.tscn") } - 检查武器节点配置
确认场景树中$Unarmed、$Pistol_A、$Rifle_A三个节点都正确挂载了对应的武器脚本,不是无脚本的原生Spatial节点。
内容的提问来源于stack exchange,提问作者Goriah
相关产品推荐
相关产品推荐

