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
相关产品推荐
相关产品推荐

