新吳區(qū)推薦做網(wǎng)站電話2021國內(nèi)最好用免費(fèi)建站系統(tǒng)
Alex教程每一P的教程原代碼加上我自己的理解初步理解寫的注釋,可供學(xué)習(xí)Alex教程的人參考
此代碼僅為較上一P有所改變的代碼
【Unity教程】從0編程制作類銀河惡魔城游戲_嗶哩嗶哩_bilibili
Inventory.cs
using Newtonsoft.Json.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class Inventory : MonoBehaviour
{public static Inventory instance;public List<ItemData> startingItem;public List<InventoryItem> equipment;//inventoryItems類型的列表public Dictionary<ItemData_Equipment, InventoryItem> equipmentDictionary;//以ItemData為Key尋找InventoryItem的字典public List<InventoryItem> inventory;//inventoryItems類型的列表public Dictionary<ItemData, InventoryItem> inventoryDictionary;//以ItemData為Key尋找InventoryItem的字典public List<InventoryItem> stash;public Dictionary<ItemData, InventoryItem> stashDictionary;[Header("Inventory UI")][SerializeField] private Transform inventorySlotParent;[SerializeField] private Transform stashSlotParent;[SerializeField] private Transform equipmentSlotParent;[SerializeField] private Transform statSlotParent;private UI_itemSlot[] inventoryItemSlot;//UI Slot的數(shù)組private UI_itemSlot[] stashItemSlot;private UI_equipementSlots[] equipmentSlot;private UI_Statslot[] statSlot;[Header("Items cooldown")]private float lastTimeUsedFlask;private float lastTimeUsedArmor;private float flaskCooldown;private float armorCooldown;private void Awake(){if (instance == null)instance = this;elseDestroy(gameObject);//防止多次創(chuàng)建Inventory}public void Start(){inventory = new List<InventoryItem>();inventoryDictionary = new Dictionary<ItemData, InventoryItem>();stash = new List<InventoryItem>();stashDictionary = new Dictionary<ItemData, InventoryItem>();equipment = new List<InventoryItem>();equipmentDictionary = new Dictionary<ItemData_Equipment, InventoryItem>();inventoryItemSlot = inventorySlotParent.GetComponentsInChildren<UI_itemSlot>();//拿到的方式有點(diǎn)繞,顯示拿到Canvas 里的 Inventory 然后通過GetComponentsInChildren拿到其下的使用UISlotstashItemSlot = stashSlotParent.GetComponentsInChildren<UI_itemSlot>();equipmentSlot = equipmentSlotParent.GetComponentsInChildren<UI_equipementSlots>();statSlot = statSlotParent.GetComponentsInChildren<UI_Statslot>();AddStartingItems();}private void AddStartingItems(){for (int i = 0; i < startingItem.Count; i++){AddItem(startingItem[i]);}}//設(shè)置初始物品public void EquipItem(ItemData _item){//解決在itemdata里拿不到子類equipment里的enum的問題ItemData_Equipment newEquipment = _item as ItemData_Equipment;//https://www.bilibili.com/read/cv15551811///將父類轉(zhuǎn)換為子類InventoryItem newItem = new InventoryItem(newEquipment);ItemData_Equipment oldEquipment = null;foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//這種方法可以同時(shí)拿到key和value保存到item里面{if (item.Key.equipmentType == newEquipment.equipmentType)//將拿到的key與轉(zhuǎn)換成itemdata_equipment類型的_item的type對(duì)比拿到存在的key{oldEquipment = item.Key;//此key需保存在外部的data類型里//equipment.Remove(item.Value);//equipmentDictionary.Remove(item.Key);}}//好像用foreach里的value和key無法對(duì)外部的list和字典進(jìn)行操作if (oldEquipment != null){AddItem(oldEquipment);Unequipment(oldEquipment);}equipment.Add(newItem);equipmentDictionary.Add(newEquipment, newItem);RemoveItem(_item);newEquipment.AddModifiers();UpdateSlotUI();}//裝備裝備的函數(shù)public void Unequipment(ItemData_Equipment itemToRemove)//裝備其他同類型的裝備時(shí)。去除已裝備的裝備{if (equipmentDictionary.TryGetValue(itemToRemove, out InventoryItem value)){equipment.Remove(value);equipmentDictionary.Remove(itemToRemove);itemToRemove.RemoveModifiers();UpdateSlotUI();}}private void UpdateSlotUI(){for (int i = 0; i < equipmentSlot.Length; i++){//此步驟用于將對(duì)應(yīng)類型的武器插入對(duì)應(yīng)的槽內(nèi)foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//這種方法可以同時(shí)拿到key和value保存到item里面{if (item.Key.equipmentType == equipmentSlot[i].slotType){equipmentSlot[i].UpdateSlots(item.Value);}}}//解決出現(xiàn)UI沒有跟著Inventory變化的bugfor (int i = 0; i < inventoryItemSlot.Length;i++){inventoryItemSlot[i].CleanUpSlot();}for (int i = 0; i < stashItemSlot.Length; i++){stashItemSlot[i].CleanUpSlot();}for (int i = 0; i < inventory.Count; i++){inventoryItemSlot[i].UpdateSlots(inventory[i]);}for (int i = 0; i < stash.Count; i++){stashItemSlot[i].UpdateSlots(stash[i]);}for(int i = 0; i < statSlot.Length;i++){statSlot[i].UpdateStatValueUI();}}//更新UI函數(shù)public void AddItem(ItemData _item){if (_item.itemType == ItemType.Equipment && CanAddItem())//修復(fù)Inventory數(shù)量大于Slot能存放的數(shù)量時(shí)報(bào)錯(cuò)的Bug{AddToInventory(_item);}else if (_item.itemType == ItemType.Material){AddToStash(_item);}UpdateSlotUI();}//添加物體的函數(shù)private void AddToStash(ItemData _item)//向stash加物體的函數(shù){if (stashDictionary.TryGetValue(_item, out InventoryItem value))//只有這種方法才能在查找到是否存在key對(duì)應(yīng)value是否存在的同時(shí),能夠同時(shí)拿到value,其他方法的拿不到value{value.AddStack();}//字典的使用,通過ItemData類型的數(shù)據(jù)找到InventoryItem里的與之對(duì)應(yīng)的同樣類型的數(shù)據(jù)else//初始時(shí)由于沒有相同類型的物體,故調(diào)用else是為了初始化庫存,使其中含有一個(gè)基本的值{InventoryItem newItem = new InventoryItem(_item);stash.Add(newItem);//填進(jìn)列表里只有一次stashDictionary.Add(_item, newItem);//同上}}private void AddToInventory(ItemData _item){if (inventoryDictionary.TryGetValue(_item, out InventoryItem value))//只有這種方法才能在查找到是否存在key對(duì)應(yīng)value是否存在的同時(shí),能夠同時(shí)拿到value,其他方法的拿不到value{value.AddStack();}//字典的使用,通過ItemData類型的數(shù)據(jù)找到InventoryItem里的與之對(duì)應(yīng)的同樣類型的數(shù)據(jù)else//初始時(shí)由于沒有相同類型的物體,故調(diào)用else是為了初始化庫存,使其中含有一個(gè)基本的值{InventoryItem newItem = new InventoryItem(_item);inventory.Add(newItem);//填進(jìn)列表里只有一次inventoryDictionary.Add(_item, newItem);//同上}}//將物體存入Inventory的函數(shù)public void RemoveItem(ItemData _item)//修復(fù)Inventory數(shù)量大于Slot能存放的數(shù)量時(shí)報(bào)錯(cuò)的Bug{if (inventoryDictionary.TryGetValue(_item, out InventoryItem value)){if (value.stackSize <= 1){inventory.Remove(value);inventoryDictionary.Remove(_item);}elsevalue.RemoveStack();}if (stashDictionary.TryGetValue(_item, out InventoryItem stashValue)){if (stashValue.stackSize <= 1){stash.Remove(stashValue);stashDictionary.Remove(_item);}elsestashValue.RemoveStack();}UpdateSlotUI();}public bool CanAddItem()//通過Inventory數(shù)量和Slot能存放的數(shù)量進(jìn)行對(duì)比,確定是否可以添加新的裝備到裝備槽{if(inventory.Count >= inventoryItemSlot.Length){Debug.Log("No more space");return false; }return true;}public List<InventoryItem> GetEquipmentList() => equipment;public List<InventoryItem> GetStashList() => stash;public ItemData_Equipment GetEquipment(EquipmentType _Type)//通過Type找到對(duì)應(yīng)的已裝備裝備的函數(shù){ItemData_Equipment equipedItem = null;foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)if (item.Key.equipmentType == _Type){equipedItem = item.Key;}return equipedItem;}public void UseFlask()//使用藥瓶設(shè)置冷卻時(shí)間{ItemData_Equipment currentFlask = GetEquipment(EquipmentType.Flask);if (currentFlask == null)return;//使用藥瓶設(shè)置冷卻時(shí)間bool canUseFlask = Time.time > lastTimeUsedFlask + flaskCooldown;if(canUseFlask){flaskCooldown = currentFlask.itemCooldown;currentFlask.Effect(null);lastTimeUsedFlask = Time.time;}else{Debug.Log("Flask is Cooldown");}}//使用藥瓶函數(shù)public bool CanUseArmor(){ItemData_Equipment currentArmor = GetEquipment(EquipmentType.Armor);if(Time.time > lastTimeUsedArmor + armorCooldown){lastTimeUsedArmor = Time.time;armorCooldown = currentArmor.itemCooldown;return true;}Debug.Log("Armor on cooldown");return false;}
}
\ItemObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ItemObject : MonoBehaviour
{private SpriteRenderer sr;[SerializeField] private Rigidbody2D rb;//設(shè)置速度[SerializeField] private ItemData ItemData;[SerializeField] private Vector2 velocity;//設(shè)置速度private void SetupVisuals(){if (ItemData == null)return;GetComponent<SpriteRenderer>().sprite = ItemData.icon;gameObject.name = ItemData.name;}public void SetupItem(ItemData _itemData,Vector2 _velocity)設(shè)置實(shí)例函數(shù){ItemData = _itemData;rb.velocity = _velocity;//設(shè)置速度SetupVisuals();}public void PickupItem()//拾取函數(shù)打包{if(!Inventory.instance.CanAddItem()&&ItemData.itemType == ItemType.Equipment)//修復(fù)在Inventory滿時(shí)撿錢裝備并銷毀它的bug{rb.velocity = new Vector2(0, 7);return;}Inventory.instance.AddItem(ItemData);Destroy(gameObject);}
}