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

Unity游戏物品栏刷新性能优化求助:批量销毁重建致卡顿

Unity物品栏UI刷新性能优化方案

核心优化思路

放弃全量销毁重建的逻辑,改为复用已有UI槽位+仅更新状态变化的槽位,同时减少不必要的内存分配与GC触发。


具体实现步骤

1. 缓存槽位UI与状态记录

先定义两个变量,分别缓存已创建的UI槽位,以及每个槽位的上一次状态(用于对比是否需要更新):

// 缓存已生成的物品槽UI实例
private List<InventoryItemUI> _cachedSlots = new List<InventoryItemUI>();
// 记录每个槽位的上一次状态(物品ID、数量),用于判断是否需要更新
private Dictionary<int, (int itemId, int count)> _lastSlotStates = new Dictionary<int, (int, int)>();

2. 优化刷新逻辑

替换原有的Redraw方法,仅做必要的UI调整与更新:

private void Redraw()
{
    int inventorySize = selectedInventory.GetSize();
    
    // 调整槽位数量:复用已有,补充不足,清理多余
    // 移除超出当前物品栏大小的槽位
    while (_cachedSlots.Count > inventorySize)
    {
        var extraSlot = _cachedSlots[^1];
        Destroy(extraSlot.gameObject);
        _cachedSlots.RemoveAt(_cachedSlots.Count - 1);
        _lastSlotStates.Remove(_cachedSlots.Count);
    }
    
    // 补充不足的槽位
    while (_cachedSlots.Count < inventorySize)
    {
        var newSlotObj = Instantiate(InventoryItemPrefab, transform);
        var slotUI = newSlotObj.GetComponent<InventoryItemUI>();
        _cachedSlots.Add(slotUI);
        
        // 初始化当前槽位的状态记录
        var currentItem = selectedInventory.GetItemAt(_cachedSlots.Count - 1);
        var initialState = (currentItem?.Id ?? -1, currentItem?.Count ?? 0);
        _lastSlotStates[_cachedSlots.Count - 1] = initialState;
        
        slotUI.Setup(selectedInventory, _cachedSlots.Count - 1);
    }
    
    // 仅更新状态发生变化的槽位
    for (int i = 0; i < inventorySize; i++)
    {
        var currentItem = selectedInventory.GetItemAt(i);
        var currentState = (currentItem?.Id ?? -1, currentItem?.Count ?? 0);
        
        // 状态未变化则跳过更新
        if (_lastSlotStates.TryGetValue(i, out var lastState) && lastState == currentState)
        {
            continue;
        }
        
        // 更新槽位UI
        _cachedSlots[i].Setup(selectedInventory, i);
        // 更新状态记录
        _lastSlotStates[i] = currentState;
    }
}

3. 内存与GC优化补充

  • 避免频繁销毁创建:如果槽位数量波动大,建议用对象池管理闲置槽位——销毁时改为禁用对象并存入池,需要时从池取出激活,彻底避免Instantiate/Destroy带来的GC开销。
  • 按需触发刷新:不要主动轮询调用Redraw,而是监听物品栏的事件(如物品添加、移除、数量变更),仅在事件触发时执行刷新。
  • 缓存资源:在Setup方法中避免重复加载物品图标等资源,提前缓存所有物品的Sprite、材质等资源,复用已有实例。
  • 谨慎触发GC:Unity的GC会自动处理内存,除非出现内存异常,否则不要主动调用GC.Collect(),建议在场景切换、加载间隙等合适时机调用。

内容的提问来源于stack exchange,提问作者Bahaa Soliman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:15:17