Unity 3D 实现拾取物品功能(一)


刚刚接触Unity不久,为了记录自己学习的过程。我决定写写博客,哈哈哈。在网上看了一些拾取物品的实现原理之后,自己摸索了一下,写了个小Demo,下面来介绍一下基本功能。1)人物靠近物体,且视角朝向物体,改变物体颜色。
2)按E键拾取物品到背包,并销毁游戏对象。
3)按B键在背包中显示已有物品。一般背包设定分为格子上限和负重上限两种,在这个Demo里我们使用格子上限的模式。且物品分为可叠加和不可叠加两种。

首先,来预览一下成果。
在游戏场景中建立这么一些游戏对象,来模拟游戏里的真实物品。

然后我们操作角色,移动到物体前。然后镜头指向游戏想,把默认颜色修改为红色。

一般游戏都使用E键拾取物品,我也使用E键拾取。拾取成功后,我们就使用Destroy()函数,销毁游戏对象。从而达到物品被加入背包的感觉。
我们把ObjectItem挂到物体上,然后设置属性。
方块1数量为685,可叠加,最大叠加数量为1000。
方块2数量为888,可叠加,最大叠加数量为1000。
相同物品的判断使用ObjId字段,所以同类物品就设置ObjId一致就可以了。

拾取以上两个方块后,按下B键,调用显示物品的函数,暂时显示到Debug控制台中。在后续的博客中再继续完善。

我们就可以看到,物品栏就有了两条记录。

然后设置两个圆柱个数都为1,且不可叠加。拾取后按B键,查看控制台

就可以看到柱子的数量分别存在的单独的格子。

把背包和物品属性抽象,形成两个类。Pack.cs和ObjectItem.cs

Pack.cs代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;public class Pack : MonoBehaviour {//保存物品的List数组public List<ItemEntity> items = null;//背包最大容量public int maxItem = 32;// Use this for initializationvoid Start () {items = new List<ItemEntity>();}//拾取物品public ObjectItem getItem(ObjectItem item){//使用中间过渡的实体类ItemEntity itemEntity = ItemEntity.FillData(item);//如果物品不可合并if (!itemEntity.IsCanAdd){   //背包有空余if(items.Count < maxItem){   //获得物品items.Add(itemEntity);item.count = 0;} else{   //拾取失败}} else{//空背包时,直接添加if (items.Count < 1){items.Add(itemEntity);item.count = 0;} else{//判断当前背包合并物品foreach (ItemEntity currItem in items){//相同物品,且可叠加,且分组未满if (currItem.ObjId.Equals(itemEntity.ObjId) && currItem.Count < currItem.MaxAdd){//数量叠加currItem.Count = currItem.Count + itemEntity.Count;//如果超出叠加范围if (currItem.Count - currItem.MaxAdd > 0){//拾取物品的剩余数量变更item.count = currItem.Count - currItem.MaxAdd;itemEntity.Count = item.count;//背包里的数量为最大值currItem.Count = currItem.MaxAdd;} else{// 未超出叠加最大值,拾取成功item.count = 0;}} else{//如果物品不是同类,或分组是满的,遍历下一个格子continue;}}//物品超出分组,有剩余格子则添加。否则剩余部分无法拾取if(item.count > 0 && items.Count < maxItem){items.Add(itemEntity);item.count = 0;}} }return item;      }//显示物品public void showPack(){string show = "物品:\n";int i = 0;foreach (ItemEntity currItem in items){  show += ++i + " [" + currItem.ObjName + "], 数量: " + currItem.Count + "\n";}Debug.Log(show);}
}

ObjectItem代码如下

using UnityEngine;
using System.Collections;public class ObjectItem : MonoBehaviour {public string objId;public string objName;public int count;public string note;public int level;public bool isCanAdd;public int maxAdd;public bool isChecked;// Use this for initializationvoid Start () {isChecked = false;}// Update is called once per frame
void Update () {if (isChecked){GetComponent<MeshRenderer>().material.color = Color.red;} else{GetComponent<MeshRenderer>().material.color = Color.white;}isChecked = false;}
}

在使用过程中,使用List保存物品时,调用Destroy()函数后,List里面的对象也会被删除掉。
所以,我们在代码中使用一个中间类ItemEntity.cs,代码如下:

public class ItemEntity {private string objId;private string objName;private int count;private string note;private int level;private bool isCanAdd;private int maxAdd;private bool isChecked;public static ItemEntity FillData(ObjectItem item){ItemEntity itemEntity = new ItemEntity();itemEntity.ObjId = item.objId;itemEntity.ObjName = item.objName;itemEntity.Count = item.count;itemEntity.Note = item.note;itemEntity.Level = item.level;itemEntity.IsCanAdd = item.isCanAdd;itemEntity.MaxAdd = item.maxAdd;itemEntity.IsChecked = item.isChecked;return itemEntity;}public string ObjId{get{return objId;}set{objId = value;}}public string ObjName{get{return objName;}set{objName = value;}}public int Count{get{return count;}set{count = value;}}public string Note{get{return note;}set{note = value;}}public int Level{get{return level;}set{level = value;}}public bool IsCanAdd{get{return isCanAdd;}set{isCanAdd = value;}}public int MaxAdd{get{return maxAdd;}set{maxAdd = value;}}public bool IsChecked{get{return isChecked;}set{isChecked = value;}}
}

最后,我们在玩家控制的角色上使用代码:

using UnityEngine;
using System.Collections;public class PlayerController : MonoBehaviour {private Transform tr;//背包类private Pack pack;// Use this for initializationvoid Start () {tr = GetComponent<Transform>();pack = GetComponent<Pack>();}// Update is called once per framevoid Update () {if (Input.GetKeyDown(KeyCode.B)){pack.showPack();}Debug.DrawRay(tr.position, tr.forward * 2.0f, Color.green);RaycastHit hit;if (Physics.Raycast (tr.position, tr.forward, out hit, 2.0f)) {//Debug.Log ("射线击中:" + hit.collider.gameObject.name + "\n tag:" + hit.collider.tag);GameObject gameObj = hit.collider.gameObject;ObjectItem obj = (ObjectItem)gameObj.GetComponent<ObjectItem>();if (obj != null){obj.isChecked = true;//Debug.Log(obj.objName);if (Input.GetKeyDown(KeyCode.E)){obj = pack.getItem(obj);if(obj.count == 0){//gameObj.SetActive(false);Destroy(gameObj);}}}}}
}

这样,我们就可以实现了拾取物品的基本功能。
当拾取超过了背包容量时,可以重叠的物品会叠加至最大数量,然后剩余数量依然存在于场景中。相当于只拾取了一部分。

代码还有很多没有使用到的属性,也是临时的一些想法,方便后续拓展。
代码变量的命名规范及代码流程还可以有更多的优化。有大牛可以给我指点指点 >.<

以上就是我摸索出来的拾取物品的一个大概模型。不知道你们是怎么实现的呢!

Unity 3D 实现拾取物品功能(一)相关推荐

  1. 【Unity 3D】使用EasyAR实现单图识别的AR增强现实功能(附实现步骤)

    EasyAR插件 接下来使用AR插件制作案例 EasyAR是免费 好用的全平台AR引擎,支持使用平面目标的AR 支持1000以上本地目标的流畅加载和识别,支持基于硬解码的视频的播放,支持二维码识别.支 ...

  2. Unity 3D游戏代码编程学习教程 Full Guide To Unity 3D C#: Learn To Code Making 3D Games

    Unity 3D游戏代码编程学习教程 Full Guide To Unity 3D & C#: Learn To Code Making 3D Games Full Guide To Unit ...

  3. 《Unity 3.x游戏开发实例》一1.5 欢迎来到Unity 3D

    本节书摘来异步社区<Unity 3.x游戏开发实例>一书中的第1章,第1.5节,作者: [加]Ryan Henson Creighton 译者: 师蓉 责编: 陈冀康,更多章节内容可以访问 ...

  4. Unity 3D:在现有的Android游戏场景中显示AdMob的横幅

    2019独角兽企业重金招聘Python工程师标准>>> 关于如何在现有的Android项目现场显示AdMob的横幅,在一个Android项目中使用一个简单的Android JAR文件 ...

  5. 日志服务接入方式之Unity 3D篇

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎. 日志 ...

  6. Unity 3D网络游戏实战 pdf

    Unity 3D网络游戏实战(全) 目录: 掌握Unity3D基本元素 1.1 简单的游戏 1.1.1在场景中创建一个立方体 1.1.2编写可以使立方体运动的程序 1.1.3测试游戏1.1.4总结1. ...

  7. Unity 3D学习笔记之一 界面介绍

    因为学校的课程,本学期对Unity 3D有学习的要求,在博客中记录下自己的Unity学习之路(内容摘录自书本和视频,书本为Unity 4.x从入门到精通) 一.Unity界面介绍      首先进入U ...

  8. Unity 3D Hierarchy视图

    Unity 3D 的 Hierarchy 视图包含了每一个当前场景的所有游戏对象(GameObject),如下图所示.其中一些是资源文件的实例,如 3D 模型和其他预制物体(Prefab)的实例,可以 ...

  9. Unity 3D 动画系统(Mecanim)|| Unity 3D 人形角色动画(Avatar)

    Unity 3D 动画系统(Mecanim) Mecanim 动画系统是 Unity 公司推出的全新动画系统,具有重定向.可融合等诸多新特性,可以帮助程序设计人员通过和美工人员的配合快速设计出角色动画 ...

最新文章

  1. php gt lte gte,springdata jpa封装数据库关键字(EQ, LIKE, GT, LT, GTE, LTE,IN)
  2. 学好python需要多久-python入门要学多久
  3. expect简单教程
  4. Longest Palindrome CodeForces - 1304B(思维)
  5. 编辑器内容FCKeditor的js验证以及FCKeditor内容是否为空判断
  6. 跑分软件测试的游戏是,主流软件跑分测试 日常游戏无压力
  7. 数据库配置不当,8.8亿条医疗记录遭泄露
  8. 信号与系统研讨(二)归一化正交函数在匹配滤波器中的应用
  9. 获取深户股市列表api_获取股票api
  10. Cesium之【高度】量算
  11. 高通about.html 文件,高通case提交指南2015Oct(4)(1)
  12. Vue+ElementUI+Tabs实现选项卡|标签页|美化标签页面|局部替换样式|好看的标签页|选项卡
  13. 优雅高效的多边形对称性判定算法
  14. 个人支付方案(免签约)-支付宝当面付开通教程
  15. 不站队的UCloud,才是最可怕的
  16. 气象卫星_全国自动站资料文件名规定(1)
  17. 基于Java的Minecraft游戏后端自定义插件 05事件监听器
  18. 被周董和郎朗拨弄,钢琴的“内心”如何掀起“波澜”?
  19. python3简明教程第二版答案_python入门简明教程?求最新的python简明教程,最好是python3的...
  20. CSDN小bug引发的思考,求赐教!

热门文章

  1. 前端面试几个基础知识自查
  2. 周常:HackerRank 算法题。(10-29~11.4)
  3. Flannel的两种模式解析(VXLAN、host-gw)
  4. python3中os.system(cmd)的返回值
  5. 百度秘钥无效的解决方法
  6. 支付宝公钥证书获取授权后用户信息
  7. 软件测试面试题:解释什么是jmeter后置处理器?
  8. 【分布式事务】分布式事务
  9. python爬虫爬取免费简历模板实例
  10. 电脑怎么备份文件?含泪分享3种免费的方法