在原本的 Inventory 的基础上,我发现一个问题,每当我需要列出一个新的列表的时候,我都需要创建一个新的 list 和 dectionary 在 Inventory 的每个方法中重新注册一遍,这太麻烦了,违背了低耦合性的原则,所以我对 inventory 重新进行了整理。
我创建了 IInventoryCategory 接口来对 Inventory 中常用的方法进行了抽象管理
IInventoryCategory.cs| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | public interface IInventoryCategory
 {
 
 ItemType GetItemType();
 
 void AddItem(ItemData item);
 
 void RemoveItem(ItemData item);
 
 void UpdateUI();
 
 void UpdateSelectedItem(ItemData selectedItem);
 
 }
 
 | 
 然后创建一个 InventoryCategory 用以管理大的类别
InventoryCategory.cs| 12
 3
 4
 5
 6
 7
 8
 9
 
 | private List<InventoryItem> items = new List<InventoryItem>();private Dictionary<ItemData, InventoryItem> itemDictionary = new Dictionary<ItemData, InventoryItem>();
 private UI_ItemSlot[] uiSlots;
 public InventoryCategory(UI_ItemSlot[] slots)
 {
 uiSlots = slots;
 }
 
 public ItemType GetItemType() => items.Count > 0 ? items[0].data.itemType : ItemType.None;
 
 | 
 同时将一些方法进行重写
- AddItem
 AddItem| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | public virtual void AddItem(ItemData item)
 {
 
 if (!itemDictionary.TryGetValue(item, out InventoryItem existingItem))
 {
 
 InventoryItem newItem = new InventoryItem(item);
 items.Add(newItem);
 itemDictionary[item] = newItem;
 }
 else
 {
 
 existingItem.AddStack();
 }
 
 
 UpdateUI();
 }
 
 |  
 
 
- RemoveItem
 RemoveItem| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | public virtual void RemoveItem(ItemData item)
 {
 
 if (itemDictionary.TryGetValue(item, out InventoryItem existingItem))
 {
 if (existingItem.stackSize > 1)
 {
 
 existingItem.RemoveStack();
 }
 else
 {
 
 items.Remove(existingItem);
 itemDictionary.Remove(item);
 }
 }
 
 
 UpdateUI();
 }
 
 |  
 
 
- UpdateUI
 | 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | public virtual void UpdateUI()
 {
 
 foreach (var slot in uiSlots)
 slot.CleanUpSlot();
 
 
 for (int i = 0; i < items.Count && i < uiSlots.Length; i++)
 {
 uiSlots[i].UpdateSlot(items[i]);
 }
 }
 
 |  
 
- UpdateSelectedItem
 UpdateSelectedItem| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | public void UpdateSelectedItem(ItemData selectedItem)
 {
 
 foreach (var item in items)
 {
 
 item.data.isSelect = item.data == selectedItem;
 }
 }
 
 
 |  
 
 
由于我需要单独列出 Equipment 下的小分类:Book 和 Weapon
所以我需要再创建一个类来对 Equipment 中的小分类进行单独的筛选以及其他操作
EquipmentCategory.cs| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 
 | using System;using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
 
 public class EquipmentCategory : MonoBehaviour, IInventoryCategory
 {
 
 private Dictionary<EquipmentType, List<InventoryItem>> typeToItems;
 
 
 private Dictionary<EquipmentType, UI_ItemSlot[]> typeToUISlots;
 
 
 public EquipmentCategory(Dictionary<EquipmentType, UI_ItemSlot[]> slotsMapping)
 {
 
 typeToItems = new Dictionary<EquipmentType, List<InventoryItem>>();
 typeToUISlots = slotsMapping;
 
 
 foreach (var type in typeToUISlots.Keys)
 {
 typeToItems[type] = new List<InventoryItem>();
 }
 }
 
 
 public ItemType GetItemType()
 {
 return ItemType.Equipment;
 }
 
 
 public void AddItem(ItemData item)
 {
 
 if (item is ItemData_Equipment equipment)
 {
 var type = equipment.equipmentType;
 
 
 var items = typeToItems[type];
 
 
 var existingItem = items.FirstOrDefault(i => i.data == item);
 if (existingItem != null)
 {
 
 existingItem.AddStack();
 }
 else
 {
 
 var newItem = new InventoryItem(item);
 items.Add(newItem);
 }
 
 
 UpdateEquipmentSlots(type);
 }
 }
 
 
 public void RemoveItem(ItemData item)
 {
 
 if (item is ItemData_Equipment equipment)
 {
 var type = equipment.equipmentType;
 
 
 var items = typeToItems[type];
 
 
 var existingItem = items.FirstOrDefault(i => i.data == item);
 if (existingItem != null)
 {
 if (existingItem.stackSize > 1)
 {
 
 existingItem.RemoveStack();
 }
 else
 {
 
 items.Remove(existingItem);
 }
 
 
 UpdateEquipmentSlots(type);
 }
 }
 }
 
 }
 
 
 | 
 然后在 Inventory 中统一注册管理这些 Category
Inventory.cs| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | private void InitializeCategories(){
 equipment = new List<InventoryItem>();
 equipmentDictionary = new Dictionary<ItemData_Equipment, InventoryItem>();
 
 inventoryItemSlot = inventorySlotParent.GetComponentsInChildren<UI_ItemSlot>();
 stashItemSlot = stashSlotParent.GetComponentsInChildren<UI_ItemSlot>();
 equipmentSlot = equpmentSlotParent.GetComponentsInChildren<UI_EquipmentSlot>();
 bookSlot = bookSlotParent.GetComponentsInChildren<UI_ItemSlot>();
 weaponSlot = weaponSlotParent.GetComponentsInChildren<UI_WeaponSlot>();
 
 equipmentSlotsMapping = new Dictionary<EquipmentType, UI_ItemSlot[]>
 {
 { EquipmentType.Book, bookSlot },
 { EquipmentType.Weapon, weaponSlot },
 
 };
 
 var equipmentCategory = new EquipmentCategory(equipmentSlotsMapping);
 categories = new Dictionary<ItemType, IInventoryCategory>
 {
 { ItemType.Equipment, equipmentCategory },
 { ItemType.Material, new InventoryCategory(stashItemSlot) }
 };
 
 }
 
 | 
 随后就可以逐一优化方法,有新的列表加入的时候就不再需要全部注册一遍方法了
以 AddItem 为例
AddItem| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 
 | public void AddItem(ItemData _item){
 if (_item == null)
 {
 Debug.LogWarning("Cannot add a null item to inventory.");
 return;
 }
 
 if (categories.TryGetValue(_item.itemType, out IInventoryCategory category))
 {
 
 if (_item is ItemData_Equipment equipment)
 {
 
 var equipmentCategory = category as EquipmentCategory;
 equipmentCategory?.AddItem(equipment);
 }
 else
 {
 
 category.AddItem(_item);
 }
 }
 else
 {
 Debug.LogWarning($"No category found for ItemType {_item.itemType}. Check your category setup.");
 }
 }
 
 |