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

C#能否将List键作为方法参数?附Unity物品升级实现问题

C# Unity物品拾取升级逻辑实现方案

现有代码核心问题

  • 循环条件逻辑错误:for(int i = 0; i >= instance.items.allItems.Count; i++)判断条件写反,列表长度大于0时循环永远不会执行,正确条件应为i < instance.items.allItems.Count
  • 静态存储结构设计错误:仅硬编码定义了private static int Whip = 0,不存在名为itemClass的静态成员,直接写Database.itemClass会触发编译错误,也无法支持多类别物品的等级记录
  • 职责耦合错误:查找物品的方法中直接修改等级数据的逻辑不合理,等级更新应放在拾取确认完成后执行

可直接运行的修正代码

用字典结构按物品类别存储当前持有最高等级,替代硬编码的单物品字段,同时拆分逻辑职责:

public class Database : MonoBehaviour
{
    public ItemDatabase items;
    private static Database instance;
    // 键为物品类别字符串,值为该类别当前持有最高等级
    private static Dictionary<string, int> ownedItemMaxLevel = new Dictionary<string, int>();

    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    /// <summary>
    /// 按类别和等级查找对应物品
    /// </summary>
    public static Item GetItemByClassAndLevel(string itemClass, int targetLevel)
    {
        for(int i = 0; i < instance.items.allItems.Count; i++)
        {
            Item currentItem = instance.items.allItems[i];
            if (currentItem.itemLevel == targetLevel && currentItem.itemClass == itemClass)
            {
                return currentItem;
            }
        }
        return null;
    }

    /// <summary>
    /// 获取所有合法可掉落物品(自动过滤已持有的低等级物品)
    /// </summary>
    public static List<Item> GetValidLootPool()
    {
        List<Item> validItems = new List<Item>();
        foreach(Item item in instance.items.allItems)
        {
            // 未持有的类别、或者是当前持有等级的下一级,才允许掉落
            if (!ownedItemMaxLevel.ContainsKey(item.itemClass) || item.itemLevel == ownedItemMaxLevel[item.itemClass] + 1)
            {
                validItems.Add(item);
            }
        }
        return validItems;
    }

    /// <summary>
    /// 拾取确认后更新持有物品记录
    /// </summary>
    public static void RecordPickedItem(Item pickedItem)
    {
        if (!ownedItemMaxLevel.ContainsKey(pickedItem.itemClass))
        {
            ownedItemMaxLevel.Add(pickedItem.itemClass, pickedItem.itemLevel);
            return;
        }
        
        if (pickedItem.itemLevel > ownedItemMaxLevel[pickedItem.itemClass])
        {
            ownedItemMaxLevel[pickedItem.itemClass] = pickedItem.itemLevel;
        }
    }
}

调用逻辑说明

  • 触发拾取时,先调用GetValidLootPool()拿到所有符合规则的可掉落物品,从中随机选择即可,不会出现重复掉落已持有低等级物品的问题
  • 玩家确认拾取后,调用RecordPickedItem()更新持有等级记录即可

关于List传参的问题解答

C#中List<T>是顺序存储的线性集合,没有内置“键”的概念,只有从0开始的整数索引:

  • 如果需要传入List的元素位置,直接传int类型的索引值作为方法参数即可,方法内部可通过索引访问对应位置元素
  • 如果需要使用自定义键值对存储/查找数据,直接使用Dictionary<TKey, TValue>类型即可,上述代码中存储持有等级的结构就是典型用法

内容的提问来源于stack exchange,提问作者Eric Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:42:18