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

Godot背包物品拖拽功能卡顿故障求助

Godot背包拖拽卡顿问题修复方案

问题根源分析

拖拽逐渐变慢甚至卡死的核心原因有三个:

  1. 重复资源加载:循环内反复调用preload("res://2D/Inventory/SelectedSlot.png"),每帧都重复加载同一份资源,导致内存占用持续攀升,拖慢程序运行。
  2. 频繁节点查找:每帧循环中多次执行get_node(),这是开销极高的操作,重复调用会快速消耗性能。
  3. 冗余逻辑执行:选中槽位纹理赋值、拖拽跟随鼠标等操作,不需要在每个槽位的循环里重复执行,完全可以只运行一次。

修复方案

1. 提前缓存资源与节点

在脚本初始化阶段预加载静态资源、缓存所有槽位按钮,避免每帧重复执行高开销操作:

var slot_buttons = {}  # 缓存所有槽位按钮节点
var selected_texture = preload("res://2D/Inventory/SelectedSlot.png")  # 预加载选中槽位纹理
var tex_selected = 0
var holding_item = false
var last_slot_selected = -1
var ist = null  # 拖拽物品的显示节点(假设已在场景中创建)

func _ready():
    ist.hide()
    # 遍历inventory缓存所有槽位按钮
    for slot_id in inventory:
        slot_buttons[slot_id] = get_node("Inventory/Slot" + slot_id + "/Button")

2. 重写优化后的inventory_up函数

将冗余逻辑移出循环,拆分功能模块,减少不必要的重复执行:

func inventory_up():
    if not can_call_inventory_up:
        return

    # 1. 检测鼠标悬停的槽位(仅执行一次遍历)
    var hovered_slot_id = -1
    for slot_id in slot_buttons:
        if slot_buttons[slot_id].is_hovered():
            hovered_slot_id = slot_id
            break

    # 更新选中槽位
    if hovered_slot_id != -1:
        tex_selected = int(hovered_slot_id)

    # 2. 更新选中槽位的纹理(仅执行一次)
    var selected_slot = get_node("Inventory/Slot" + str(tex_selected))
    selected_slot.texture = selected_texture

    # 3. 处理拖拽逻辑(独立于槽位循环)
    if Input.is_action_pressed("UseItem"):
        if not holding_item and hovered_slot_id != -1:
            # 开始拖拽
            var target_slot = get_node("Inventory/Slot" + hovered_slot_id)
            ist.position = target_slot.position
            ist.texture = inventory[hovered_slot_id]["image"]
            ist.show()
            last_slot_selected = int(hovered_slot_id)
            holding_item = true
        elif holding_item:
            # 拖拽跟随鼠标(仅执行一次)
            ist.global_position = get_viewport().get_mouse_position()
    else:
        # 松开鼠标放置物品
        if holding_item and hovered_slot_id != -1 and int(hovered_slot_id) != last_slot_selected:
            swap_slots(str(last_slot_selected), hovered_slot_id)
            holding_item = false
            ist.hide()

# 辅助函数:交换两个槽位的物品数据
func swap_slots(slot_a: String, slot_b: String):
    # 临时存储A槽位物品
    var temp_item = {
        "name": inventory[slot_a]["name"],
        "max_store": inventory[slot_a]["max_store"],
        "current_store": inventory[slot_a]["current_store"],
        "image": inventory[slot_a]["image"],
        "object": inventory[slot_a]["object"]
    }

    # 将B槽位物品移至A
    inventory[slot_a] = inventory[slot_b].duplicate()
    # 将临时物品移至B
    inventory[slot_b] = temp_item

    # 若目标槽位原本为空,清空原槽位(根据需求调整)
    if inventory[slot_b]["name"] == "":
        inventory[slot_a] = {
            "name": "",
            "max_store": 1,
            "current_store": 0,
            "image": null,
            "object": null
        }

关键优化点说明

  • 资源预加载:选中槽位纹理仅在初始化时加载一次,彻底避免重复加载导致的内存泄漏。
  • 节点缓存:槽位按钮节点提前存入字典,每帧无需重复查找节点,大幅降低性能开销。
  • 逻辑精简:悬停检测、拖拽跟随等操作仅执行一次,不再遍历每个槽位重复运行。
  • 代码复用:用辅助函数swap_slots处理物品交换,减少冗余代码,提升可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:43:13