Godot 4自定义资源拖拽数据交换失效问题求助
问题
我正在制作一个技能槽界面,允许玩家自由搭配、调整技能顺序。单向拖拽功能正常,但实现两个节点间数据交换时持续报错。
我定义了名为Ability的自定义资源,技能槽节点(AbilitySlot)拥有selected_ability变量,用于存储该资源并设置纹理等信息。
代码如下:
extends TextureRect class_name AbilitySlot @export var selected_ability: Ability @onready var slot: AbilitySlot = $"./" func _process(_delta): if selected_ability: slot.texture = selected_ability.icon else: slot.texture = null func _get_drag_data(_at_position): set_drag_preview(get_preview()) global.origin_slot = self.get_name() global.origin_ability = self.selected_ability print(global.origin_slot) print(global.origin_ability) return slot.selected_ability func get_preview(): var preview_texture = TextureRect.new() if selected_ability: preview_texture.texture = slot.selected_ability.icon preview_texture.expand_mode = 1 preview_texture.size = Vector2(64,64) var preview = Control.new() preview.add_child(preview_texture) return preview func _can_drop_data(_at_position, data): global.target_slot = get_name() if selected_ability: global.target_ability = selected_ability else: global.target_ability = null print(global.target_slot) print(global.target_ability) return true func _drop_data(_at_position, data): global.origin_slot.selected_ability = global.target_ability # ERROR selected_ability = global.origin_ability
程序在倒数第二行报错:Invalid set index 'selected_ability' (on base: 'StringName') with value of type 'Resource (Ability)'。
注释该行后,目标槽可成功复制源槽内容,但源槽内容不变,无法实现交换效果。请问实现数据交换时,正确处理源槽的方式是什么?
解决方案
报错核心原因:global.origin_slot存储的是节点的名称字符串(StringName类型),并非技能槽节点的实例,因此无法直接通过它访问selected_ability变量。
要实现技能交换,只需将源槽的节点实例存入全局变量,而非节点名称,具体修改如下:
- 修改
_get_drag_data函数,保存节点实例而非名称:
func _get_drag_data(_at_position): set_drag_preview(get_preview()) global.origin_slot = self # 存储当前节点实例,不是名称 global.origin_ability = self.selected_ability print(global.origin_slot.name) # 需要打印名称时调用.name属性 print(global.origin_ability) return slot.selected_ability
- 修正
_drop_data中的交换逻辑,直接通过节点实例操作变量:
func _drop_data(_at_position, data): # 临时保存目标槽当前的技能 var temp_ability = selected_ability # 目标槽替换为源槽的技能 selected_ability = global.origin_ability # 源槽替换为目标槽原来的技能 global.origin_slot.selected_ability = temp_ability
这样就能完成两个技能槽的技能交换。另外可以优化掉global.target_ability变量,直接在_drop_data中读取当前槽的selected_ability,减少全局变量冗余。
内容的提问来源于stack exchange,提问作者l8r_allocator
相关产品推荐
相关产品推荐

