【Unity】仓库逻辑:拾取物体进仓库和扔掉物品

news/2025/1/11 22:57:23/文章来源:https://www.cnblogs.com/sitarblogs/p/18545415

需求说明

目标:实现玩家移动过程中,拾取物体,物体被放入仓库;点击仓库中物体,重新扔回3D场景中逻辑。

逻辑分析:

  • 需要玩家可以移动;
  • 需要检测玩家和物体的碰撞,并摧毁物体;
  • 需要识别物体的类别;
  • 新物体直接新建,已有的物体增加数量;
  • 需要记录仓库的物体详情列表,并响应列表的变化;
  • 需要仓库的UI界面,点击物体可以生成物体到3D中;
  • 需要提供物体的素材,可以动态的增删和展示物体。

成果展示

Scene部分

玩家移动

需要绑定移动相关的脚本

碰撞检测

两个物体能够检测到碰撞,需要至少一个物体绑定刚体组件,需要绑定碰撞体组件,碰撞体组件需要勾选 isTrigger 属性。

被绑定刚体组件的物体,需要取消勾选 use gravity 重力属性,才能阻止物体自然下落(不在平面上的情况)。

识别物体

将需要放进仓库中的物体,做成 profab 预制体。

定义不同的 tag 区分物体类别。

UI仓库栏

建议做成滚动界面【点击查看相关文章】,应对仓库物品多的情况。

仓库栏中展示物体使用 Image 组件,不同的物品对应不同的图片。

制作单个物体UI模板,当有物品增删到仓库时,只需要实例化该模板,修改其中的物体图片和数量即可。

动态素材

新建空物体,绑定素材资源输入的脚本

脚本部分

类的设计

物体类

包括可以放入仓库的物体信息,物体名称、物品个数、物体对应的Profab、物体对应的UI图片等。

public class Goods
{private GoodsName goodsName;private int num;public Goods(GoodsName goodsName){this.goodsName = goodsName;num = 1;}public void AddNum(){num++;}public void DecNum(){num--;}public int GetNum(){return num;}public GoodsName GetGoodsName(){return goodsName;}public Sprite GetSprite(){switch (goodsName){case GoodsName.Cube:return GameAsset.instance.Cube;case GoodsName.Cylinder:return GameAsset.instance.Cylinder;default:return null;}}public Transform GetProfab(){switch (goodsName){case GoodsName.Cube:return GameAsset.instance.CubeTransform;case GoodsName.Cylinder:return GameAsset.instance.CylinderTransform;default:return null;}}
}
仓库类

管理仓库,包括物品列表、增删物品等。

public class Inventory
{//列表发生变化时触发public event EventHandler OnItemListChanged;private List<Goods> goodsList;private Action<Goods> useGoodsAction;public Inventory(List<Goods> goodsList, Action<Goods> useGoodsAction){this.goodsList = goodsList;this.useGoodsAction = useGoodsAction;}//增加时,新物体加入列表,已有的物体改变数量public void AddGoods(GoodsName goodsName){Goods target = goodsList.Find(_ => _.GetGoodsName() == goodsName);if (target != null){target.AddNum();}else{Goods goods = new Goods(goodsName);goodsList.Add(goods);}OnItemListChanged?.Invoke(this, EventArgs.Empty);}//删除时,数量为1的物体从列表移除,否则只改变数量public void DeleteGoods(GoodsName goodsName){Goods target = goodsList.Find(_ => _.GetGoodsName() == goodsName);if (target != null){if (target.GetNum() == 1){goodsList.Remove(target);}else{target.DecNum();}}OnItemListChanged?.Invoke(this, EventArgs.Empty);}public List<Goods> GetGoodsList() {return goodsList;}//需要使用仓库中的物品public void UseGoods(Goods goods) {useGoodsAction(goods);}
}

素材脚本

提供不同物体的素材

public class GameAsset : MonoBehaviour
{public static GameAsset instance;private void Awake(){instance = this;}public Sprite Cube;public Sprite Cylinder;public Transform CubeTransform;public Transform CylinderTransform;
}

玩家脚本

键盘按键控制玩家移动;

检测与物体的碰撞;

实例化仓库类;

建立仓库UI和仓库类的关系;

public class Player : MonoBehaviour
{[SerializeField] private float moveSpeed = 20f;private void Update(){//玩家的移动Vector3 inputDir = new Vector3(0, 0, 0);if (Input.GetKey(KeyCode.UpArrow)) inputDir.z += +1f;if (Input.GetKey(KeyCode.DownArrow)) inputDir.z += -1f;if (Input.GetKey(KeyCode.LeftArrow)) inputDir.x += -1f;if (Input.GetKey(KeyCode.RightArrow)) inputDir.x += +1f;Vector3 moveDir = transform.forward * inputDir.z + transform.right * inputDir.x;transform.position += moveDir * moveSpeed * Time.deltaTime;}Inventory inventory;[SerializeField] UI_Inventory ui_inventory;private void Awake(){inventory = new Inventory(new List<Goods>(), (goods) =>{//使用物体时,删除仓库中的物体,生成新的物体预制体,并随机扔在3D场景中。inventory.DeleteGoods(goods.GetGoodsName());Instantiate(goods.GetProfab(), new Vector3(UnityEngine.Random.Range(-20, 20), 0, UnityEngine.Random.Range(-20, 20)), new Quaternion());});//初始化UIui_inventory.Init(inventory);}void OnTriggerEnter(Collider c){//可以放进仓库的物体,增加到仓库,同时摧毁3d场景中的物体if (Enum.TryParse(c.gameObject.tag, true, out GoodsName goodsName)){inventory.AddGoods(goodsName);Destroy(c.gameObject);}}
}

UI脚本

随着仓库物品的列表变化而更新;

点击UI, 可以使用物品;

public class UI_Inventory : MonoBehaviour
{Transform itemTemplate;List<Transform> itemTransformList;Inventory inventory;public void Init(Inventory inventory){this.inventory = inventory;inventory.OnItemListChanged += Inventory_OnItemListChanged;//记录物体UI模板itemTemplate = transform.Find("itemTemplate");itemTransformList = new List<Transform>();}//事件: 列表变化,刷新UIprivate void Inventory_OnItemListChanged(object sender, System.EventArgs e){UpdateItemsList();}//列表变化,刷新UIprivate void UpdateItemsList(){//先删除所有UI的物体itemTransformList.ForEach(_ =>{Destroy(_.gameObject);});itemTransformList.Clear();//重新加载仓库类中的物品列表inventory.GetGoodsList().ForEach(goods =>{Transform itemTemplateTransform = Instantiate(itemTemplate, transform);itemTemplateTransform.gameObject.SetActive(true);//输入对应物品图片和数量itemTemplateTransform.Find("Image").GetComponent<Image>().sprite = goods.GetSprite();itemTemplateTransform.Find("text").GetComponent<TextMeshProUGUI>().SetText(goods.GetNum().ToString());itemTransformList.Add(itemTemplateTransform);//点击物品,触发事件itemTemplateTransform.GetComponent<Button_UI>().ClickFunc = () => {inventory.UseGoods(goods);};});}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么卷积现在不火了:CNN研究热度降温的深层原因分析

在深度学习领域,卷积神经网络(CNN)曾经是计算机视觉的代名词。自2012年AlexNet在ImageNet竞赛中取得突破性成功以来,CNN在图像识别、目标检测等领域掀起了一场革命。然而,纵观近年的顶会论文和研究热点,我们不得不承认一个现实:CNN相关的研究论文正在减少,曾经的"…

hostapd移植到RK356X

1. 简介开发环境:Ubuntu20.04目标平台:RK356X,内核版本:4.19.234hostapd版本:2.10, 依赖特定版本的openssl和libnlopsnssl版本:3.0.15libnl版本:3.2.32. openssl 移植hostapd依赖openssl,需要先移植openssl获取openssl源码,选择使用3.0.15版本,链接如下https://openssl…

最全面的输入法教程:后话

完结撒花~🎉🎉🎉最后,本文就来讲讲一些更加进阶的场景,以及一些感想。 ‍ 特殊场景 如果你有输入生僻字的需求,可以看看这篇文章:【技术贴】快速输入生僻字 - 知乎 此外除了输入汉字,学术方面还有时候得输入数学公式,此时就可以考虑用 LaTex 了,具体可以看我这篇文…

【最优化方法】第三次要点整理

目录非精确线搜索技术Armijo-Goldstein 准则Wolfe-Powell 准则强 Wolfe-Powell 准则 【问题】在迭代中,已知 \(x^{(k)}\) 和下降方向 \(d^{(k)}\),如何确定下降步长 \(\alpha^{(k)}\),使得 \(f(x^{(k)} + \alpha^{(k)} d^{(k)}) < f(x^{(k)})\)? 非精确线搜索技术 求 \(…

AlignSum:数据金字塔与层级微调,提升文本摘要模型性能 | EMNLP24

来源:晓飞的算法工程笔记 公众号,转载请注明出处论文: AlignSum: Data Pyramid Hierarchical Fine-tuning for Aligning with Human Summarization Preference论文地址:https://arxiv.org/abs/2410.00409 论文代码:https://github.com/csyanghan/AlignSum创新点发现在文本摘…

快速提升职场效率:从整理任务清单开始

在职场中,我们总会面对各种大小不一的任务,常常让人有种“任务无处不在、却无从下手”的感觉。有效地管理工作,既需要掌握具体的任务管理方法,也需要选择一款适合的工具帮助我们更高效地完成这些任务。今天就从最基础的“整理任务清单”说起,分享一些提高职场效率的实用技…

ABB IRB5500喷涂机器人电机维修故障方法

ABB喷涂机器人电机在运行过程中可能会遇到多种常见故障,用户需根据电机的实际运行状况,细致地进行故障辨析并采取适当的处理措施。在进行维修作业时,务必严格遵守安全操作规程,确保不会对机器人本身及维修人员造成任何伤害。 一、ABB喷涂机器人电机维修故障现象的初步判断与…

NocoBase 本周更新汇总:提升工作流易用性

汇总一周产品更新日志,最新发布可以前往我们的博客查看。 NocoBase 目前更新包括两个分支:main 和 next 。 main :截止目前最稳定的版本,推荐安装此版本。 next:内测版,包含一些未发布的新特性,这个版本可能还不完全稳定,适用于开发者或测试人员,用于提前体验新功能或…

AD(活动目录)环境下使用kms服务自动激活域里windows

AD(活动目录)环境下使用kms服务自动激活域里windows 做基础架构运维对AD域架构和kms激活应该是比较熟悉的,关于kms激活服务器搭建,可以看看网上的相关资料,其安装在CentOS比较稳定,当然也支持其他类似的OS。安装过程不再赘述了。希望能够帮助大家! 可以参考: bbs.pcbet…

Mac和安卓手机互传文件(ADB)

点赞 + 关注 + 收藏 = 学会了 本文简介 今年的 Mac mini M4 真的鲨疯了,丐版原价4字头,领到国补的3字头可以拿下。相信很多想体验 macOS 的工友都蠢蠢欲动了。 但是,电脑便宜了,手机可不便宜。对于正在使用 「苹果电脑 + 安卓手机」 的工友来说,想让这两设备互传体积大、数…

什么是数字图像?

点赞 + 关注 + 收藏 = 学会了 什么是数字图像? 弄懂数字图像的概念对学习计算机视觉很有帮助。 那么,什么是数字图像? 字面意思,数字图像就是有数字组成图像。通常由像素(Pixel)组成,每个像素包含颜色或亮度信息。数字图像的格式包括位图和矢量图两种主要类型:位图图像…

经销商文件外发,如何实现安全与效率的双赢?

经销商文件外发是指经销商在业务运营过程中,与供应商、客户、合作伙伴以及其他相关方之间进行的文件接收和发送活动。这些文件涵盖了订单、发票、合同、产品目录、库存报告、市场活动资料、运输单据、客户反馈等多种类型,对于经销商的日常运营、业务管理、客户关系维护以及决…