Unity吃鸡背包系统笔记

news2024/11/29 12:38:52

功能需求

  1. 查看玩家拥有的所有物品,可以放下其中的任意物品;
  2. 查看已死的他人背包的物品,可以拿起其中的任意物品;
  3. 查看附近的物品,可以拿起其中的任意物品(暂时不考虑背包容量);

难点

1.背包里的物品数据存在脚本里,玩家不可能直接在检查器面板查看背包的物品,必须把它们呈现到UI界面上,这就使同一份数据在脚本和UI界面存在两份,必须使两份数据保持一致。玩家通过UI界面操作改变脚本里的数据时,为了保持两份数据一致理论上UI界面的数据必须总是从脚本读取,而不能直接操作UI界面,比如从场景拿一个弹匣到背包里,如果用代码把附近物品栏的这个弹匣删掉,再在背包物品栏加上这个弹匣,实际上进行了脚本数据和UI界面的两线操作,造成了两边数据不一致的可能性。比如如果弹匣UI的脚本记录的是自己在背包物品列表的索引,玩家拿起了不是最后一个的弹匣,那么被拿起弹匣后面的弹匣在背包物品列表的索引实际上变化了,这时候就应该把附近物品列表的所有物品删除,重新从脚本读取显示。

2.玩家从场景拿起一个物品放进背包时需要把该物品销毁,从背包放下物品时需要把物品实例化。实例化时需要知道实例化哪个物品,背包里的物品没有场景里的实例,只是数据,这个数据就要记录如果自己被放到场景里需要实例化一个什么物体,即记录自己的预制体。

背包里记录弹匣数据的结构体定义为:

[Serializable]
    public struct MagInPack{
        public Mag magPrefab;
        public int ammoNum;
        public MagInPack(Mag magPrefab, int ammoNum){
            this.magPrefab=magPrefab;
            this.ammoNum=ammoNum;
        }
    }

然后我发现拾取场景里的弹匣时我只知道这个实体弹匣,这个弹匣放进背包时这个物体就销毁了,背包里的弹匣数据结构体需要记录弹匣的预制体,也就是场景里的弹匣实体都要记录自己的预制体,捡起放进背包时存入弹匣结构体。

然后我发现让一个预制体的脚本里一个引用指向预制体它自己,预制体实例化后这个引用指向的也是场景里的实例它自己了。不能让一个预制体脚本里的引用指向它自己来记录预制体。

a413e75dc9144c1fa85825e82adff209.gif

背包里的弹匣结构体保存有它的预制体,放下弹匣的时候把预制体引用传给实例的预制体引用;拿起弹匣的时候则从实例的预制体引用传给背包里的结构体。

f3fe4a646cb945e08215959c158e4048.png

背包界面的物品UI,在场景里的有对应物体,在玩家背包里和附近其他人背包里的物品在场景里没有物体,都要生成物品UI。

525ac761f8fe4f4fbabf5dcef2d16f84.png

 子弹信息记录的数据结构

而换弹的逻辑我没写把背包的子弹加到弹匣,而是没打完的弹匣放回背包,在弹匣队列尾部。这样背包里的子弹数不能用一个数字记录,必须用一个列表:

293f50114a544ef1bf6422e5111b62db.png

这样换弹的时候会麻烦点,需要在列表里遍历,直到找到需要的子弹。

后来发现,如果换弹逻辑做成把背包里的子弹加到弹匣里,那么应该定义子弹种类的枚举,然后使用相同子弹的不同枪从同一个子弹数字段里取子弹;如果换弹逻辑做成把背包里的弹匣换上,没打完的弹匣放回背包,那么使用相同子弹的不同枪的弹匣也是不通用的,比如G17和M9使用同一种子弹,但是弹匣不通用,容弹量不一样,应该定义枪的型号的枚举,定义子弹型号的枚举就没有意义。

需要做的测试

1.点开背包界面,显示的物品和人物拥有的一致

c8a02a5b0e59487a92faefebbc0486ca.png

2.走近其他物品,点开背包界面,其他物品出现在附近物品栏

0221c2455c164514b99b76a0468cb412.png

3.点拥有的枪或物品,把它放下,此物品出现在附近物品栏;如果是弹匣这样在背包里没有实体的物品,附近应该出现它的实体

f3fe4a646cb945e08215959c158e4048.png749f42d3df534a6a9825554b57ccf325.pngfd6131d434544d898e6c1e8880095ad4.png

4.捡起身上没有的物品,此物品从附近物品栏消失,加入拥有的物品;如果是弹匣,此物品在场景里的实体消失

5.和附近的枪交换

6.打开背包界面查看附近的物品,按F拾取,再打开背包界面,该物品从附近物品栏消失

7.打开背包界面查看附近的物品,按F放下枪,再打开背包界面,该物品出现在附近物品栏

附近物品列表及其维护

背包脚本声明了一个列表记录周围可拾取的物品:

5e5d2b73204a4d98be8ddd3d97323e44.png

如果不做可拾取物品列表,背包界面不显示附近可拾取物品,拾取物品一律按F拾取,背包系统会简单很多。但是就无法拿其他人背包里的物品。

Physics.OverlapSphere()检测附近物品

打开背包界面时用Physics.OverlapSphere()得到一个球形区域的碰撞体,筛选出可拾取的、没有主人的物品,加入附近物品列表。加之前要先把附近物品列表清空。

 public float pickUpRange=2;
    public LayerMask packCheckLayerMask;
    public void CheckItemsAround(){
        itemsAround.Clear();
        packsAround.Clear();
        Collider[] thingsAround=Physics.OverlapSphere(transform.position,pickUpRange,packCheckLayerMask);//检测周围球形区域里的物品
        Item item;
        Weapon gun;
        MyCharacter other;
        for(int i=0;i<thingsAround.Length;i++){
            if(thingsAround[i].TryGetComponent(out item)){//检测到是物品
                if(item is Weapon){
                    gun=item as Weapon;
                    if(gun!=myCharacter.rifleScript&&gun!=myCharacter.pistolScript&&gun.owner==null){//不是人物自己的枪&&枪没有主人
                        itemsAround.Add(item);
                    }
                }
            }
            else if(thingsAround[i].TryGetComponent(out other)){//检测到是人
                if(other.life<=0&&other.backpack){//人已经死了&&人有背包
                    for(int j=0;j<other.backpack.magsInPack.Count;j++){
                        packsAround.Add(other.backpack);
                    }
                }
            }
            
        }
    }

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

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

相关文章

《Linux系统编程篇》fork函数——基础篇

文章目录 引言fork() 函数概述父子进程 fork函数fork() 的常见问题fork() 的优势与限制 结论 命为志存。 —— 朱熹 引言 《Linux系统编程篇》——基础篇首页传送门 本节我们正式进入Linux的进程代码编写。 fork() 是 Unix 系统中一个重要的系统调用&#xff0c;用于创建一个…

MySQL 8 下载与安装攻略

MySQL是一个流行的关系型数据库管理系统&#xff0c;目前MySQL属于Oracle公司的&#xff0c;关于MySQL的详细介绍可以参考&#xff1a; MySQL 的完整介绍 本篇主要关注MySQL 的下载和安装。 MySQL 下载 官方下载 进入MySQL 的下载页面 &#xff1a;https://dev.mysql.com/do…

HarmonyOS 鸿蒙开发 路由跳转报错this uri is empty, not support in route push.

检查方案1&#xff1a; 工程目录下 entry > src > main > resources > base > profile > main_pages.json中检查是否配置了NextPage 检查方案2&#xff1a; 在路由跳转的代码中检查是否路径配置错误 这里要注意&#xff0c;url的路径一定要和main_pages.json…

芯片上音频相关的验证

通常芯片设计公司&#xff08;比如QUALCOMM&#xff09;把芯片设计好后交由芯片制造商&#xff08;比如台积电&#xff09;去生产&#xff0c;俗称流片。芯片设计公司由ASIC部门负责设计芯片。ASIC设计的芯片只有经过充分的验证&#xff08;这里说的验证是FPGA&#xff08;现场…

【VSCode】配置

安装插件 C vscode-icons gdb调试 https://www.bilibili.com/video/BV15U4y1x7b2/?spm_id_from333.999.0.0&vd_sourcedf0ce73d9b9b61e6d4771898f1441f7f https://www.bilibili.com/video/BV1pU4y1W74Z?spm_id_from333.788.recommend_more_video.-1&vd_sourcedf0…

springboot使用枚举作为接口的参数

1.定义枚举类 2.定义接口 3.具体实现方法 4.apifox传入参数 枚举的具体’名称’就可以了 5.调试 6.进入断点&#xff0c;这样我们发现在接口的参数就映射到应的枚举类上了

数据结构(8.4_3)——堆的插入删除

在堆中插入新元素 在堆中删除元素 总结&#xff1a;

《计算机网络网络层:连接虚拟世界的关键桥梁》

一、网络层概述 网络层在计算机网络中占据着至关重要的地位&#xff0c;它作为连接不同网络的关键层次&#xff0c;起着承上启下的作用。网络层的主要任务是实现网络互连&#xff0c;将数据设法从源端经过若干个中间节点传送到目的端&#xff0c;为分组交换网上的不同主机提供通…

【linux】fdisk磁盘分区管理

介绍 fdisk是一个磁盘分区管理工具&#xff0c;可以用来创建、删除、修改和查看磁盘分区。 fdisk一般都是交互式使用&#xff0c;基础语法: fdisk /dev/sdd。进入交互窗口后&#xff0c;有一些选项&#xff0c;需要了解下&#xff1a; 选项含义n创建新分区p查看磁盘的分区情…

项目成本管理系统有哪些功能?9款工具详解

本文推荐的9大主流项目成本管理工具有: 1. PingCode&#xff1b;2. Worktile&#xff1b;3. 用友U8项目管理&#xff1b;4. 金蝶K3 Cloud&#xff1b;5. 泛微e-Project&#xff1b;6. 亿方云项目管理&#xff1b; 7. SAP Project System&#xff1b; 8. Trello&#xff1b; 9. …

基于opencv的眼镜试戴系统

对于正在准备毕业设计或者想在技术项目上加点“创新”的同学们&#xff0c;推荐一款基于OpenCV的眼镜试戴系统&#xff01;这不仅是一个实现个人创意的项目&#xff0c;更是一个结合AI技术和实用应用的完美范例。 &#x1f31f; 系统核心功能&#xff1a; 图片试戴&#xff1a…

解决cuda环境使用dgl

Dgl 是实现图结构数据构造的工具包&#xff0c;想在gpu环境下使用它&#xff0c;如果安装的是pip install dgl 会有下面错误 dgl._ffi.base.DGLError: [09:10:13] /opt/dgl/src/runtime/c_runtime_api.cc:82: Check failed: allow_missing: Device API cuda is not enabled. P…

软考高级备考记录

一 报考条件和报名流程 报考条件 该考试具有水平考试性质&#xff0c;报考任何级别不需要学历、资历条件&#xff0c;只要达到相应的专业技术水平就可以报考相应的级别 报名流程 软考报名官网&#xff1a;中国计算机技术职业资格网 官网上有 报名时间&#xff0c;考试…

springboot077基于SpringBoot的汽车票网上预订系统--论文pf(论文+源码)_kaic

汽车票网上预订系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了汽车票网上预订系统的开发全过程。通过分析汽车票网上预订系统管理的不足&#xff0c;创建了一个计算机管理汽车票网上预订系统的方案。文章…

vue使用xlsx以及file-saver进行下载xlsx文件以及Unit8Array、ArrayBuffer、charCodeAt的使用

先说Unit8Array、ArrayBuffer、charCodeAt的使用下面会用到这三个 Unit8Array&#xff1a;数组类型表示一个 8 位无符号整型数组&#xff0c;创建时内容被初始化为 0。创建完后&#xff0c;可以以对象的方式或使用数组下标索引的方式引用数组中的元素。 new Uint8Array(); //…

Python中的数据可视化:Matplotlib基础与高级技巧

Python中的数据可视化&#xff1a;Matplotlib基础与高级技巧 数据可视化是数据分析和数据科学中不可或缺的一部分。通过图表&#xff0c;我们可以更直观地观察数据的分布和趋势。Matplotlib作为Python最基础、也是最广泛使用的绘图库之一&#xff0c;不仅支持多种常用图表&…

Android Studio中Gradle一直在加载怎么解决(首次安装过程中)

目录 前言&#xff1a;遇到问题&#xff1a;已解决&#xff1a; 前言&#xff1a; Android Studio中Gradle一直在加载怎么解决&#xff08;首次安装过程中&#xff09;&#xff0c;在安装Android Studio的过程中&#xff0c;我因为环境的问题&#xff0c;被困扰了一天&#xf…

合合信息发布智能文档处理“百宝箱”,助力文档应用开发

文档是知识传递的载体&#xff0c;无论是大模型应用发展&#xff0c;还是与产业数字化息息相关的高质量数据库的建立&#xff0c;都离不开对于文档数据的处理和分析。目前&#xff0c;越来越多的开发者开始关注文档数据处理背后的“文档解析”技术&#xff0c;用以实现自动化数…

python常见内置函数

介绍Python常见的内置函数。 1、abs 取一个数的绝对值 int_value -2 print(abs(int_value))2、all 若一个可迭代对象(可循环遍历的对象)中所有元素为真&#xff0c;结果为真 list_value1 [1,2,3,4,0] list_value2 [1,2,3,4] print(all(list_value1)) print(all(list_va…

【cmake实战六】如何使用编译的库(动态库dll)——windows系统

【cmake实战六】如何使用编译的库&#xff08;动态库dll&#xff09;——windows系统_make windows下生成库-CSDN博客 基于以上文章&#xff0c;遇到的一些问题&#xff1a; 一、首先我用vs code 新建了一个项目&#xff1a;TEST 新增文件&#xff1a;CMakeList.txt #…