首页 > 其他分享 >Unity类银河战士恶魔城学习总结(P124 Limit Inventory Slots 限制库存槽位)

Unity类银河战士恶魔城学习总结(P124 Limit Inventory Slots 限制库存槽位)

时间:2024-11-14 09:14:21浏览次数:3  
标签:P124 ItemData void private 恶魔城 item Unity 物品 public

【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

相关文章

  • 【Unity 天气系统插件】Enviro 3 - Sky and Weather 高度可定制的云、雾和光照系统
    Enviro3-SkyandWeather是一款功能强大的Unity插件,专门用于模拟逼真的天空、天气和环境效果。它适用于需要动态天气和日夜循环的游戏或应用,如开放世界RPG、模拟类游戏等。Enviro3提供了大量的设置选项和自定义功能,帮助开发者在Unity中创建沉浸式的自然环境效果。......
  • 【Unity第一人称射击游戏 (FPS) 动画框架】FPS Animation Framework ,提供了 武器动画
    FPSAnimationFramework是一款为Unity提供的专门用于第一人称射击游戏(FPS)的动画框架插件。它旨在帮助开发者快速实现FPS游戏中的角色控制、武器操作、动作与动画等核心功能。通过该框架,开发者可以轻松创建高质量、流畅的动画效果,提高玩家的沉浸感与游戏的打击感......
  • 【Unity怪物角色资源包】Fantasy Monsters Animated [Megapack] 丰富的怪物模型,快速充
    FantasyMonstersAnimated[Megapack]是一款为Unity开发的怪物角色资源包,包含了大量动画怪物模型,特别适合RPG、幻想冒险和动作游戏。该资源包不仅提供了种类丰富的怪物模型,还包括多种动画,帮助开发者快速创建复杂且生动的敌人角色。此资源包非常适合想要打造魔幻或中......
  • 【Unity着色器插件】Better Lit Shader 2021 增强光照和材质表现,在性能和美观度上做出
    BetterLitShader2021是一款在Unity中广受欢迎的着色器插件,主要用于增强光照和材质表现。它在性能和美观度上做出平衡,非常适合希望在Unity中实现高质量视觉效果的开发者,特别是那些想要获得逼真光照效果的项目。主要功能多光照支持:支持多个光源在场景中同时使用,例如主光......
  • 【Unity人群寻路插件】CrowdPath Pathfinding 高效的路径规划算法来模拟群体寻路行为,
    CrowdPathPathfinding是一款专为Unity设计的路径寻找插件,主要用于处理复杂的人群导航问题,特别适合需要大规模虚拟人物群体移动的游戏或应用。它通过高效的路径规划算法来模拟群体行为,如避开障碍、避免拥挤、相互避让等。主要特点:高效的人群路径寻找:插件能够在复杂环境......
  • Unity类银河战士恶魔城学习总结(P123 UI)UI创建的开始
    【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/本章节实现了UI的初步创建层级的设置UI.cs详细工作原理:1.遍历并隐藏所有子元素:transform.childCount:获取当前对象下所有子对象的数量。transform......
  • 施耐德UNITY下使用ST编程计算最近一小时的均值
    昨晚学习练习了ST语言做最近60秒的分钟均值,今天继续做最近一小时的均值,1秒采集一次数据。在昨晚程序上增加功能,新建一个导出的功能块类型Average_Hour,定义下面的变量:旗下新建一个程序段Average_Hour,使用ST编程Minute1:=BCD_TO_INT(%SW51);Minute:=mod_int(Minute1,100);Second1......
  • 【Unity】UGUI中ScrollView的设置
    UI实现横向滚动展示元素,并可以点击指定项增加元素。成果展示Scene部分ScrollView的设置此案例取消了纵向的滚动条,可以直接删除对应的Scrollbar,然后取消勾选ScrollRect中的Vertical属性;MovementType属性选择了Clamped(无滚动到头尾反弹效果),默认是Elastic选项(反弹效果),根据个......
  • unity项目托管代码和非托管代码之间的数据传递原理刨析
    Unity3D架构Unity3D是一个广泛使用的游戏引擎,支持多种平台的游戏开发。它的架构主要由两部分组成:非托管代码(UnmanagedCode):这部分主要是用C++编写的,负责引擎的底层功能,如图形渲染、物理计算、音频处理等。非托管代码直接与操作系统和硬件交互,通常具有更高的性能,但开......
  • P2123 皇后游戏 / [USACO12JAN] Mountain Climbing S / P1248 加工生产调度 题解
    P2123皇后游戏/[USACO12JAN]MountainClimbingS/P1248加工生产调度先来看P2123。我们把这个特别重要的公式打出来:\[c_{i}=\begin{cases}a_{1}+b_{1}&,i=1\\\displaystyle\max\left\{c_{i-1},\sum_{j=1}^{i}a_{j}\right\}+b_{i}&,2\leqi\leqn\end{......