Unity类银河恶魔城学习记录12-3 p125 Limit Inventory Slots源代码

news2024/10/9 18:21:33

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习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的数组
    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;
        else
            Destroy(gameObject);
        //防止多次创建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>();//拿到的方式有点绕,显示拿到Canvas 里的 Inventory 然后通过GetComponentsInChildren拿到其下的使用UISlot
        stashItemSlot = 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]);
        }
    }//设置初始物品

    public void EquipItem(ItemData _item)
    {
        //解决在itemdata里拿不到子类equipment里的enum的问题
        ItemData_Equipment newEquipment = _item as ItemData_Equipment;//https://www.bilibili.com/read/cv15551811/
        //将父类转换为子类
        InventoryItem newItem = new InventoryItem(newEquipment);

        ItemData_Equipment oldEquipment = null;

        foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//这种方法可以同时拿到key和value保存到item里面
        {
            if (item.Key.equipmentType == newEquipment.equipmentType)//将拿到的key与转换成itemdata_equipment类型的_item的type对比拿到存在的key
            {
                oldEquipment = item.Key;//此key需保存在外部的data类型里
                //equipment.Remove(item.Value);
                //equipmentDictionary.Remove(item.Key);
            }
        }//好像用foreach里的value和key无法对外部的list和字典进行操作

        if (oldEquipment != null)
        {
            AddItem(oldEquipment);
            Unequipment(oldEquipment);
        }
            

        equipment.Add(newItem);
        equipmentDictionary.Add(newEquipment, newItem);
        RemoveItem(_item);
        newEquipment.AddModifiers();
        UpdateSlotUI();
        
    }//装备装备的函数

    public void Unequipment(ItemData_Equipment itemToRemove)//装备其他同类型的装备时。去除已装备的装备
    {
        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++)
        {
            //此步骤用于将对应类型的武器插入对应的槽内
            foreach (KeyValuePair<ItemData_Equipment, InventoryItem> item in equipmentDictionary)//这种方法可以同时拿到key和value保存到item里面
            {
                if (item.Key.equipmentType == equipmentSlot[i].slotType)
                {
                    equipmentSlot[i].UpdateSlots(item.Value);
                }
            }

        }
        //解决出现UI没有跟着Inventory变化的bug
        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].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函数

    public void AddItem(ItemData _item)
    {
        if (_item.itemType == ItemType.Equipment && CanAddItem())//修复Inventory数量大于Slot能存放的数量时报错的Bug
        {
            AddToInventory(_item);
        }
        else if (_item.itemType == ItemType.Material)
        {
            AddToStash(_item);
        }


        UpdateSlotUI();
    }//添加物体的函数

    private void AddToStash(ItemData _item)//向stash加物体的函数
    {
        if (stashDictionary.TryGetValue(_item, out InventoryItem value))//只有这种方法才能在查找到是否存在key对应value是否存在的同时,能够同时拿到value,其他方法的拿不到value
        {
            value.AddStack();
        }//字典的使用,通过ItemData类型的数据找到InventoryItem里的与之对应的同样类型的数据
        else//初始时由于没有相同类型的物体,故调用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))//只有这种方法才能在查找到是否存在key对应value是否存在的同时,能够同时拿到value,其他方法的拿不到value
        {
            value.AddStack();
        }//字典的使用,通过ItemData类型的数据找到InventoryItem里的与之对应的同样类型的数据
        else//初始时由于没有相同类型的物体,故调用else是为了初始化库存,使其中含有一个基本的值
        {
            InventoryItem newItem = new InventoryItem(_item);
            inventory.Add(newItem);//填进列表里只有一次
            inventoryDictionary.Add(_item, newItem);//同上
        }
    }//将物体存入Inventory的函数

    public void RemoveItem(ItemData _item)//修复Inventory数量大于Slot能存放的数量时报错的Bug
    {
        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)
            {
                stash.Remove(stashValue);
                stashDictionary.Remove(_item);
            }
            else
                stashValue.RemoveStack();
        }

        UpdateSlotUI();
    }
    public bool CanAddItem()//通过Inventory数量和Slot能存放的数量进行对比,确定是否可以添加新的装备到装备槽
    {
        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找到对应的已装备装备的函数
    {
        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("Flask is Cooldown");
        }
    }//使用药瓶函数

    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;//设置速度
    [SerializeField] private ItemData ItemData;
    [SerializeField] private Vector2 velocity;//设置速度


    private void SetupVisuals()
    {
        if (ItemData == null)
            return;

        GetComponent<SpriteRenderer>().sprite = ItemData.icon;
        gameObject.name = ItemData.name;
    }
   
    public void SetupItem(ItemData _itemData,Vector2 _velocity)设置实例函数
    {
        ItemData = _itemData;
        rb.velocity = _velocity;//设置速度

        SetupVisuals();
    }

    public void PickupItem()//拾取函数打包
    {
        if(!Inventory.instance.CanAddItem()&&ItemData.itemType == ItemType.Equipment)//修复在Inventory满时捡钱装备并销毁它的bug
        {
            rb.velocity = new Vector2(0, 7);
            return;
        }
        Inventory.instance.AddItem(ItemData);
        Destroy(gameObject);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1568325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 线程:线程互斥、互斥量、可重入与线程安全

目录 一、线程互斥 1、回顾相关概念 2、抢票场景分析代码 多个线程同时操作全局变量 产生原因 如何解决 二、互斥量 1、概念 2、初始化互斥量&#xff1a; 方法1&#xff1a;静态分配 方法2&#xff1a;动态分配 3、销毁互斥量&#xff1a; 4、加锁和解锁 示例抢…

多忽悠几次AI全招了!Anthropic警告:长上下文成越狱突破口,GPT羊驼Claude无一幸免

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 大模型厂商在上下文长度上卷的不可开交之际&#xff0c;一项最新研究泼来了一盆冷水—— Cl…

计算机网络-HTTP相关知识-HTTP的发展

HTTP/1.1 特点&#xff1a; 简单&#xff1a;HTTP/1.1的报文格式包括头部和主体&#xff0c;头部信息是键值对的形式&#xff0c;使得其易于理解和使用。灵活和易于扩展&#xff1a;HTTP/1.1的请求方法、URL、状态码、头字段等都可以自定义和扩展&#xff0c;使得其具有很高的…

Golang 内存管理和垃圾回收底层原理(一)

一、这篇文章我们来聊聊Golang内存管理和垃圾回收&#xff0c;主要注重基本底层原理讲解&#xff0c;进一步实战待后续文章 1、这篇我们来讨论一下Golang的内存管理 先上结构图 从图我们来讲Golang的基本内存结构&#xff0c;内存结构可以分为&#xff1a;协程缓存、中央缓存…

Redis的高可用(主从复制、哨兵模式、集群)的概述及部署

目录 一、Redis主从复制 1、Redis的主从复制的概念 2、Redis主从复制的作用 ①数据冗余&#xff1a; ②故障恢复&#xff1a; ③负载均衡&#xff1a; ④高可用基石&#xff1a; 3、Redis主从复制的流程 4、Redis主从复制的搭建 4.1、配置环境以及安装包 4.2所有主机…

chabot项目介绍

项目介绍 整体的目录如下所示&#xff1a; 上述的项目结构中出了model是必须的外&#xff0c;其他的都可以根据训练的代码参数传入进行调整&#xff0c;有些不需要一定存在data train.pkl:对原始训练语料进行tokenize之后的文件,存储一个list对象&#xff0c;list的每条数据表…

解密AI人工智能的整体分层架构:探索智能科技的未来之路

随着人工智能技术的迅猛发展&#xff0c;AI已经渗透到我们生活的方方面面。而支撑AI人工智能系统运作的核心是其整体分层架构。本文将深入探讨AI人工智能的整体分层架构&#xff0c;揭示其中的奥秘&#xff0c;探索智能科技的未来之路。 ### AI人工智能整体分层架构的重要性 …

Linux上安装DM8(达梦数据库),SpringBoot集成达梦

1.达梦数据库在Linux上的安装 官方手册:https://eco.dameng.com/document/dm/zh-cn/start/install-dm-linux-prepare.html 1.1下载安装包 官网:https://www.dameng.com/list_103.html 点击”服务与合作”--> “下载中心” 这里选择对应的cpu和操作系统(举个例子:windows版本…

Java基础 - 代码练习

第一题&#xff1a;集合的运用&#xff08;幸存者&#xff09; public class demo1 {public static void main(String[] args) {ArrayList<Integer> array new ArrayList<>(); //一百个囚犯存放在array集合中Random r new Random();for (int i 0; i < 100; …

JimuReport 积木报表

一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于 excel 操作风格&#xff0c;通过拖拽完成报表设计…

从零到百万富翁:ChatGPT + Pinterest

原文&#xff1a;Zero to Millionaire Online: ChatGPT Pinterest 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 在社交媒体上赚取百万美元 - 逐步指南&#xff0c;如何在线赚钱版权 献给&#xff1a; 我将这本书&#xff0c;“从零到百万富翁在线&#xff1a;Chat…

【御控物联】JavaScript JSON结构转换(18):数组To对象——多层属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、案例之《JSON数组 To JSON对象》三、代码实现四、在线转换工具五、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0c;生成新的JS…

基于PHP的校园招聘管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的校园招聘管理系统 一 介绍 此校园招聘管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为个人用户&#xff0c;企业和管理员三种。 技术栈&#xff1a;phpmysqlbootstrapphpstudyvscode 二…

JS——判断节假日(假日包括周末,不包括调休上班的周末)

思路&#xff1a;创建两个数组&#xff0c;数组1为节假日数组&#xff0c;数组2为是周末上班日期数组。如果当前日期&#xff08;或某日期&#xff09;同时满足2个条件&#xff08;1.在节假日数组内或在周末。2.不在周末上班日期数组&#xff09;即为节假日&#xff0c;否则即为…

Mybatis-Plus05(分页插件)

分页插件 MyBatis Plus自带分页插件&#xff0c;只要简单的配置即可实现分页功能 1. 添加配置类 Configuration MapperScan("com.atguigu.mybatisplus.mapper") //可以将主类中的注解移到此处 public class MybatisPlusConfig {Bean public MybatisPlusIntercepto…

LeetCode-105. 从前序与中序遍历序列构造二叉树【树 数组 哈希表 分治 二叉树】

LeetCode-105. 从前序与中序遍历序列构造二叉树【树 数组 哈希表 分治 二叉树】 题目描述&#xff1a;解题思路一&#xff1a;暴力搜索解题思路二&#xff1a;哈希查找解题思路三&#xff1a; 题目描述&#xff1a; 给定两个整数数组 preorder 和 inorder &#xff0c;其中 pr…

通过vite创建项目

一、VUE3官网 Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org) 二、通过Vite创建项目 1、在cmd窗口下&#xff0c;全局安装vite //使用国内镜像源 npm config set registryhttps://registry.npmmirror.com//安装最新版vite npm install -g vitelatest Vite | 下一代…

Python爬虫——基于JWT的模拟登录爬取实战

基于JWT的模拟登录爬取实战 JWT&#xff08;JSON Web Token&#xff09;主要由三部分组成&#xff1a; Header&#xff1a;包含了Token的类型&#xff08;“typ”&#xff09;和签名算法&#xff08;“alg”&#xff09;信息。通常情况下&#xff0c;这个部分会指定为{"…

ChatGPT 之创造力与沟通的演化

原文&#xff1a;ChatGPT … The Evolution of Creativity and Communication 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 作者注 亲爱的读者&#xff0c; ChatGPT&#xff0c;一位 AI 专家和一位律师走进了一家酒吧。酒保看着他们说&#xff1a;“这是什么&…

企业邮箱给谷歌Gmail报错550-5.7.25解决方案

企业邮箱给谷歌Gmail报错550-5.7.25解决方案 问题表现 今天接到同事报告企业邮箱发送报错的问题&#xff0c;具体问题表现如下&#xff1a; 我司内部邮箱 xxXXX.com 邮箱给国内的163和新浪和企业内部发送邮件可以成功给Hotmail发送邮件&#xff0c;成功。给Gmail发送邮件&am…