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

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变量。

要实现技能交换,只需将源槽的节点实例存入全局变量,而非节点名称,具体修改如下:

  1. 修改_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
  1. 修正_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:52:41