【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节实现了仓库满了不能添加物品,而且会摧毁物品的Bug
并且增加了背包满了拾取物品的一个小动画
ItemObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//创建一个物体,放入这个脚本
public class ItemObject : MonoBehaviour
{
[SerializeField] private Rigidbody2D rb;
[SerializeField] private ItemData itemData;//就是你放入的图标
private void SetupVisuals()//设置物品的图标和名称
{
if (itemData == null)
return;
GetComponent<SpriteRenderer>().sprite = itemData.icon;//在编辑器中显示图标
gameObject.name = "Item object - " + itemData.itemName;//直接在编辑器中显示名字
}
public void SetupItem(ItemData _itemData,Vector2 _velocity)//配置物品的数据和掉落的初始速度
{
itemData = _itemData;
rb.velocity = _velocity;
SetupVisuals();
}
public void PickupItem()//将物品添加到背包,然后销毁
{
//11月12日改
if (!Inventory.instance.CanAddItem() && itemData.itemType == ItemType.Equipment)//如果不能添加物品并且物品类型是装备
{
rb.velocity = new Vector2(0, 7);
return;
}
Inventory.instance.AddItem(itemData);
Destroy(gameObject);
}
}
Inventory.cs
添加的部分!!!
public bool CanAddItem()
{
if( inventory.Count >= inventoryItemSlot.Length)
{
Debug.Log("仓库已满");
return false;
}
return true;
}
using System.Collections.Generic;
using UnityEngine;
//放在创建仓库的empyty对象上,就是仓库的运行函数
public class Inventory : MonoBehaviour
{
public static Inventory instance;//单例模式
public List<ItemData> startingItems;//初始装备
//两种关键的存贮结构
//List:存储玩家的装备、仓库物品、储藏室物品等
//Dictionary:存储每个物品的数据以及物品在仓库中的具体信息,例如物品的堆叠数量
public List<InventoryItem> equipment;
public Dictionary<ItemData_Equipment, InventoryItem> equipmentDictionary;
public List<InventoryItem> inventory;
public Dictionary<ItemData, InventoryItem> inventoryDictionary;
public List<InventoryItem> stash;
public Dictionary<ItemData, InventoryItem> stashDictionary;
//UI物品槽管理:通过以下代码将游戏中的物品槽和UI界面上的物品槽关联起来
[Header("仓库UI")]//Inventory UI
[SerializeField] private Transform inventorySlotParent;//位置
[SerializeField] private Transform stashSlotParent;
[SerializeField] private Transform equipmentSlotParent;
[SerializeField] private Transform statSlotParent;
//物品和材料的存贮位置分开
private UI_ItemSlot[] inventoryItemSlot;
private UI_ItemSlot[] stashItemSlot;//储藏室
private UI_EquipmentSlot[] equipmentSlot;//装备
private UI_StatSlot[] statSlot;
[Header("物品冷却")]
private float lastTimeUsedFlask;
private float lastTimeUsedArmor;
//P122解决一开始不能用物品的问题,因为一开始冷却被赋值,使用了currentFlask.itemCoolDown
private float flaskCoolDown;
private float armorCoolDown;
private void Awake()
{
if (instance == null)
instance = this;
else
Destroy(gameObject);//防止从一个地方到另一个地方
}
private 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>();
//同时获取UI中对应的物品槽
//获得起始的脚本
inventoryItemSlot = inventorySlotParent.GetComponentsInChildren<UI_ItemSlot>();
stashItemSlot = stashSlotParent.GetComponentsInChildren<UI_ItemSlot>();
equipmentSlot = equipmentSlotParent.GetComponentsInChildren<UI_EquipmentSlot>();
statSlot = statSlotParent.GetComponentsInChildren<UI_StatSlot>();
AddStartingItems();
}
private void AddStartingItems()//添加初始物品
{
for (int i = 0; i < startingItems.Count; i++)
{
AddItem(startingItems[i]);
}
}
public void EquipItem(ItemData _item)//把一个物品装备到角色身上
{
ItemData_Equipment newEquipment = _item as ItemData_Equipment;//把 _item 对象转换为 ItemData_Equipment 类型,表示它是一个装备物品
InventoryItem newItem = new InventoryItem(newEquipment); //把 ItemData 对象转换为 InventoryItem 对象
ItemData_Equipment oldEquipment = null;//要删除的物品
foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//遍历装备字典
{
if (item.Key.equipmentType == newEquipment.equipmentType)//如果装备类型相同
oldEquipment = item.Key;//删除该装备
}
if (oldEquipment != null)
{
UnequipItem(oldEquipment);
AddItem(oldEquipment);//把要删除的物品放回仓库
}
equipment.Add(newItem);
equipmentDictionary.Add(newEquipment, newItem);
newEquipment.AddModifiers();//添加装备属性
RemoveItem(_item);
UpdataSlotsUI();
}
public void UnequipItem(ItemData_Equipment itemToRemove)//移除装备函数
{
if (equipmentDictionary.TryGetValue(itemToRemove, out InventoryItem value))
{
equipment.Remove(value);
equipmentDictionary.Remove(itemToRemove);
itemToRemove.RemoveModifiers();
}
}
private void UpdataSlotsUI()//更新UI物体的数量
{
// 更新装备槽
for (int i = 0; i < equipmentSlot.Length; i++)//将装备物品槽与一个装备字典中的物品进行匹配,并根据匹配结果更新物品槽的内容
{
foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//遍历装备字典
{
if (item.Key.equipmentType == equipmentSlot[i].slotType)//这个条件用于确保物品能放入正确的槽位中
equipmentSlot[i].UpdataSlot(item.Value);
}
}
// 清空并更新仓库和储藏室的物品槽
for (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].UpdataSlot(inventory[i]);
}
for (int i = 0; i < stash.Count; i++)
{
stashItemSlot[i].UpdataSlot(stash[i]);
}
//更新属性槽
for (int i = 0; i < statSlot.Length; i++)
{
statSlot[i].UpdateStatValueUI();
}
}
public void AddItem(ItemData _item)//据物品类型,将物品添加到仓库(inventory)或者储藏室(stash)
{
if (_item.itemType == ItemType.Equipment && CanAddItem())
{
AddToInventory(_item);
}
else if (_item.itemType == ItemType.Material)
{
AddToStash(_item);
}
UpdataSlotsUI();
}
private void AddToStash(ItemData _item)
{
if (stashDictionary.TryGetValue(_item, out InventoryItem value))
{
value.AddStack();
}
else
{
InventoryItem newItem = new InventoryItem(_item);
stash.Add(newItem);
stashDictionary.Add(_item, newItem);
}
}
private void AddToInventory(ItemData _item)
{
if (inventoryDictionary.TryGetValue(_item, out InventoryItem value))//字典中检查仓库中是否有这个物品,具体查找的是ItemData,out InventoryItem value如果找,返回与该键相关联的值
{
value.AddStack();//如果物品已经存在于库存中,则增加其堆叠数量
}
else
{
InventoryItem newItem = new InventoryItem(_item);//如果物品不存在,则创建一个新的 InventoryItem
inventory.Add(newItem);
inventoryDictionary.Add(_item, newItem);
}
}//检查物品是否已经在仓库里,如果存在则增加堆叠数量,如果不存在则创建新的物品对象并加入仓库
public void RemoveItem(ItemData _item)
{
if (inventoryDictionary.TryGetValue(_item, out InventoryItem value))
{
if (value.stackSize <= 1)
{
inventory.Remove(value);
inventoryDictionary.Remove(_item);
}
else
{
value.RemoveStack();
}
}
if (stashDictionary.TryGetValue(_item, out InventoryItem stashValue))
{
if (stashValue.stackSize <= 1)//如果物品的堆叠数量小于等于1,则从库存中删除该物品
{
stash.Remove(stashValue);
stashDictionary.Remove(_item);
}
else
{
stashValue.RemoveStack();//否则就减少堆寨数量
}
}
UpdataSlotsUI();
}
public bool CanAddItem()
{
if( inventory.Count >= inventoryItemSlot.Length)
{
Debug.Log("仓库已满");
return false;
}
return true;
}
public bool CanCraft(ItemData_Equipment _itemToCraft, List<InventoryItem> _requiredMaterials)//判断是否可以合成的函数
{
List<InventoryItem> materialsToRemove = new List<InventoryItem>();
for (int i = 0; i < _requiredMaterials.Count; i++)
{
if (stashDictionary.TryGetValue(_requiredMaterials[i].data, out InventoryItem stashValue))//如果储藏室中没有所需材料
{
if (stashValue.stackSize < _requiredMaterials[i].stackSize)//数量是否足够
{
Debug.Log("没有足够的材料");
return false;
}
else
{
materialsToRemove.Add(stashValue);
}
}
else
{
Debug.Log("没有足够的材料");
return false;
}
}
for (int i = 0; i < materialsToRemove.Count; i++)//使用了就从临时仓库中移除
{
RemoveItem(materialsToRemove[i].data);
}
AddItem(_itemToCraft);
Debug.Log("这里是你的物品" + _itemToCraft.name);
return true;
}
public List<InventoryItem> GetEquipmentList() => equipment;//获取装备列表
public List<InventoryItem> GetStashList() => stash;//获取仓库列表
public ItemData_Equipment GetEquipment(EquipmentType _type)//获取装备
{
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()//使用药水的函数
{
ItemData_Equipment currentFlask = GetEquipment(EquipmentType.Flask);//获取当前的药水
if (currentFlask == null)
return;
bool canUseFlask = Time.time > lastTimeUsedFlask + flaskCoolDown;//判断是否可以使用药水
if (canUseFlask)
{
flaskCoolDown = currentFlask.itemCoolDown;//重置冷却时间,一开始就可以使用物品
currentFlask.Effect(null);
lastTimeUsedFlask = Time.time;
}
else
Debug.Log("药水冷却中");
}
public bool CanUseArmor()
{
ItemData_Equipment currentArmor = GetEquipment(EquipmentType.Armor);//获取当前装备的护甲信息。
if (Time.time > lastTimeUsedArmor + armorCoolDown)
{
//更新冷却时间和使用时间
armorCoolDown = currentArmor.itemCoolDown;
lastTimeUsedArmor = Time.time;
return true;
}
Debug.Log("护甲正在冷却中");
return false;
}
//private void Updata()
//{
// Debug.Log(Time.time);
//}
}
标签:P124,ItemData,void,private,恶魔城,item,Unity,物品,public
From: https://blog.csdn.net/suzh1qian/article/details/143712568