欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > Unity吃鸡背包系统笔记

Unity吃鸡背包系统笔记

2025/6/17 4:50:11 来源:https://blog.csdn.net/Jesui/article/details/143315309  浏览:    关键词:Unity吃鸡背包系统笔记

功能需求

  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);}}}}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词