文章目录

  • 10.1 流浪喵星
  • 10.2 碰撞的必要条件
    • 10.2.1 Collider,碰撞器组件
    • 10.2.2 Rigidbody,刚体组件
  • 10.3 碰撞器类型
    • 10.3.1 Static Collider,静态碰撞器
    • 10.3.2 Rigidbody Collider,刚体碰撞器
    • 10.3.3 Kinematic Rigidbody Collider,运动学刚体碰撞器
  • 10.4 碰撞事件
  • 10.5 触发器事件
  • 10.6 射线碰撞检测

简介:我是一名Unity游戏开发工程师,皮皮是我养的猫,会讲人话,它接到了喵星的特殊任务:学习编程,学习Unity游戏开发。
于是,发生了一系列有趣的故事。

10.1 流浪喵星

2020年,喵星所在的拉姆达星系中,巨大的鲁特恒星即将毁灭,已经不适合喵星人生存,面对绝境,喵星人开启了 “流浪喵星” 计划,试图带着喵星一起逃离拉姆达星系,寻找喵星人新的家园。
然而,喵星在靠近纳美星的时候被强大的引力吸住,马上就要撞上去了,情况十分危急。
皮皮:“呼叫铲屎官,呼叫铲屎官,只剩最后1分钟了。”
我:“请点燃纳美星!”
皮皮:“来不及了。”
我:“以下是命令 :活下去!”

皮皮:“奇迹出现了,喵星直接穿透了纳美星。”

10.2 碰撞的必要条件

皮皮:“铲屎官,你刚刚是怎么做到的?”
我:“最后关头,我将纳美星的碰撞器禁用了,避免了这次物理碰撞。”

Unity3D内置物理引擎,可以模拟物理效果。典型的一个物理效果就是碰撞。
两个物体发生物理碰撞的必要条件是:两个物体都带有Collider(碰撞器)组件,其中一个物体带有Rigidbody(刚体)组件,并且是运动的物体带有Rigidbody组件。

10.2.1 Collider,碰撞器组件

Collider,即碰撞器。Unity中提供了各种形状的碰撞器组件。点击AddComponent,可以看到如下的各种碰撞器组件,这些碰撞器组件名字带2D的都是继承自Collider2D类,名字没带2D的都继承自Collider类,一般3D物体的使用Collider碰撞器,2D物体使用Collider2D碰撞器。

我们通过3D Object菜单创建的几何体都默认带了相应的碰撞器组件。

比如创建球体Sphere,它会自带球形碰撞器组件Sphere Collider

10.2.2 Rigidbody,刚体组件

Rigidbody,刚体组件,刚体能让你的游戏对象被物理引擎所控制,它能通过受到推力和扭力来实现真实的物理表现效果。

我们可以通过给刚体施加一个力来改变一个它的运动状态:

// 获取刚体组件
Rigidbody rigidBody = gameObject.GetComponent<Rigidbody>();
// 给刚体一个向量为(1, 0, 0)的力
rigidBody.AddForce(new Vector3(1, 0, 0));

刚体受到力的作用,会改变运动状态。假设初始状态是禁止的,那么施加一个力之后,刚体会动起来。动起来的速度与刚体受到的力成正比,与刚体的质量成反比。
RigidbodyMass属性就是刚体的质量。

使用代码设置刚体的质量:

// 设置刚体的质量为1
rigidBody.mass = 1;

我们要可以直接给刚体设置速度:

// 给刚体设置速度
rigidBody.velocity = new Vector3(1, 0, 0);

另外,还可以设置角速度:

// 给刚体设置角速度
rigidBody.angularVelocity = new Vector3(0, 1, 0);

有了角速度,物体就会开始旋转。

刚体的运动状态还会受到空气阻力的影响,RigidbodyDrag属性就是刚体的空气阻力,默认为0,即空气阻力为0。

通过代码设置刚体的空气阻力:

// 设置刚体的空气阻力为0
rigidBody.drag = 0;

物体的旋转受到角阻力Angular Drag的影响。

通过代码设置刚体的角阻力:

// 设置刚体的角阻力为0.05f
rigidBody.angularDrag = 0.05f;

皮皮拿过鼠标,点击AddComponent,添加了刚体组件。

刚体的属性如下:

点击运行Unity

皮皮:“怎么回事呀?球体直接垂直往下掉了。”
我:“因为Rigidbody有个Use Gravity属性,意思就是是否使用重力,默认是勾选着的,所以球体就受到重力作用直接垂直往下掉了。”

去掉Use Gravity的勾选,移动球体,可以产生碰撞了,不过如果移动速度快一点,还是可以穿过去。

皮皮:“这又是怎么回事呀?”
我:“因为我们是强行拖拉来移动刚体物体的,并不是由物理引擎来驱动移动,刚体的碰撞检测不是连续的。另外,被撞的物体是一个静态碰撞器,我们这样强行拉着刚体移动,只要速度稍快一些就会出现穿透现象。”
皮皮:“你解释一个问题,中间又引入了新的概念,什么是静态碰撞器?”

10.3 碰撞器类型

10.3.1 Static Collider,静态碰撞器

静态碰撞器是指只挂了Collider而没挂Rigidbody的游戏对象。这类对象会保持静止或者很轻微的移动。这类碰撞器被刚体碰撞后不会移动。
皮皮:“难怪刚刚被撞的另一个球不会动,因为它是一个静态碰撞器。”

10.3.2 Rigidbody Collider,刚体碰撞器

刚体碰撞器是指既挂了Collider又挂了Rigidbody的游戏对象。运动的刚体碰撞器可以与静态碰撞器发生碰撞,两个刚体碰撞器之间也可以发生碰撞。如果刚体碰撞器禁止不动,强行移动静态碰撞器去碰刚体碰撞器,此时并不会发生碰撞,因为禁止的刚体碰撞器会进入休眠状态。

10.3.3 Kinematic Rigidbody Collider,运动学刚体碰撞器

运动学刚体碰撞器是指在刚体碰撞器的基础上,激活了Kinematic的游戏对象。
要移动这类游戏对象,要修改它的Transform组件(坐标或角度),而不能通过力。

我:“运动学刚体碰撞器是个非常懒惰和霸道的家伙,它不受力、重力或扭矩的影响,它去碰别人,它自己不会受到反作用力。所以你可以把运动学刚体碰撞器看成一个所向披靡的碰撞器,谁遇到它都不是对手。”
皮皮:“那如果两个运动学刚体碰撞器相互碰撞会怎样?”
我:“谁也不让谁,直接穿透过去。”

10.4 碰撞事件

MonoBehavior脚本中,我们可以通过OnCollisionEnterOnCollisionStayOnCollisionExit来处理收碰撞事件。其中collision参数是对方的碰撞器对象,脚本挂在两个碰撞体上都可以触发OnCollisionXXX

private void OnCollisionEnter(Collision collision)
{Debug.Log("碰撞进入");
}private void OnCollisionStay(Collision collision)
{Debug.Log("碰撞中");
}private void OnCollisionExit(Collision collision)
{Debug.Log("碰撞结束");
}

10.5 触发器事件

有时候我们并不想产生物理碰撞的效果,但是又想检测碰撞器之间的碰撞事件,这个时候就可以使用触发器。
触发器其实是碰撞器,只是勾选了Is Trigger
MonoBehavior脚本中,我们可以通过OnTriggerEnterOnTriggerStayOnTriggerExit来处理收碰撞事件。

private void OnTriggerEnter(Collider other)
{Debug.Log("触发进入");
}private void OnTriggerStay(Collider other)
{Debug.Log("触发中");
}private void OnTriggerExit(Collider other)
{Debug.Log("触发结束");
}

想要产生触发器事件,两个碰撞器中至少要有一个勾选了Is Trigger,并且其中一个要带Rigidbody组件。
皮皮:“触发器有什么应用吗?看起来不知道用在哪里。”
我:“举个简单的例子,你走近一个门的时候,要触发播放开门的动作,那么门就可以弄成触发器。门的碰撞体可以稍微调大一点,这样人就可以提前碰到触发器,触发开门动作。”

10.6 射线碰撞检测

皮皮:“可不可以实现一个鼠标拖动物体的功能,这样就可以直接用鼠标拖动喵星逃离兰姆达星系啦。”
我:“可以呀,原理很简单,点击鼠标左键,从摄像机的位置往里发射射线,检测到碰撞,则把碰撞体缓存到一个对象中,移动鼠标的时候,把鼠标坐标转成世界坐标赋值给刚刚的物体,实现鼠标抓取物体移动的效果,鼠标松开时,释放缓存对象。”

Demo工程如下,把下文的TouchAndMoveObj .cs脚本挂在某个GameObject即可,比如挂在Main Camera上。

运行效果:

TouchAndMoveObj .cs脚本代码如下:

using UnityEngine;public class TouchAndMoveObj : MonoBehaviour
{private Transform m_targetTrans;private Camera cam;private float m_posZ;private void Start(){cam = Camera.main;}private void Update(){// 鼠标左键按下if (Input.GetMouseButtonDown(0)){Ray ray = cam.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit, 100)){// 缓存射线碰撞到的物体m_targetTrans = hit.transform;// 缓存物体与摄像机的距离m_posZ = m_targetTrans.position.z - cam.transform.position.z;}}// 鼠标左键抬起if (Input.GetMouseButtonUp(0)){// 释放碰撞体缓存m_targetTrans = null;}// 鼠标按住中if (null != m_targetTrans && Input.GetMouseButton(0)){// 鼠标的屏幕坐标转成世界坐标// 由于鼠标的屏幕坐标的z轴是0,所以需要使用物体距离摄像机的距离为z周的值var targetPos = cam.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, m_posZ)); ;// 让物体的坐标跟着鼠标走m_targetTrans.position = targetPos;}}
}

《学Unity的猫》——第十一章:Unity猫咪救济管理系统,山岗的星光

《学Unity的猫》——第十章:Unity的物理碰撞,流浪喵星计划相关推荐

  1. 《学Unity的猫》——第九章:状态机与Unity协程,好奇猫与铁皮怪水管

    文章目录 9.1 会吐水的铁皮怪 9.2 状态机是什么 9.3 使用协程实现状态机 9.4 进程与线程 9.4.1 什么是进程 9.4.2 什么是线程 9.5 Unity的协程 9.5.1 Unity ...

  2. 《学Unity的猫》——第十九集:皮皮猫上班第一天,认识游戏开发公司各个部门

    文章目录 19.1 皮皮正式上班 19.2 部门职责 19.2.1 财务部 19.2.2 行政/人事部 19.2.3 运维部 19.2.4 市场部 19.2.5 策划部 19.2.6 美术部 19.2 ...

  3. 《学Unity的猫》——第一章:故事开始

    文章目录 1.1 关于我 1.2 关于我的猫--皮皮 1.3 hello,喵 1.1 关于我 大家好,我是一名程序员,职业是Unity游戏开发工程师,每天上班下班,偶尔画画,弹弹吉他,写写博客.日子就 ...

  4. 《学Unity的猫》——第十二章:使用Unity制作背包,皮皮的梦想背包

    文章目录 12.1 皮皮的梦想背包 12.2 准备道具图片 12.3 UGUI打图集 12.3.1 设置图集模式:Always Enabled(Legacy Sprite Packer) 12.3.2 ...

  5. 《学Unity的猫》——第十八集:Unity3D游戏开发工程师笔试刷题,皮皮收到面试邀请

    文章目录 18.1 皮皮收到面试邀请 18.2 面试题库相关网站 18.2.1 牛客网 18.2.2 领扣LintCode 18.2.3 力扣LeetCode 18.3 优质学习网站 18.3.1 菜 ...

  6. 《学Unity的猫》——第十一章:Unity猫咪救济管理系统,山岗的星光

    文章目录 11.1 山岗的星光 11.2 Unity猫咪救济管理系统 11.3 设置UI摄像机 11.4 设置Canvas 11.5 制作登录界面预设 11.6 制作大厅界面预设 11.7 制作信息界 ...

  7. 《学Unity的猫》——第八章:Unity预设文件,无限纸团喷射机

    文章目录 8.1 无限纸团喷射机 8.2 预设是什么 8.3 预设的制作 8.4 预设的修改 8.4.1 Open Prefab--进入神秘世界 8.4.2 退出神秘世界 8.4.3 Override ...

  8. 《学Unity的猫》——第五章:规范Unity的工程目录结构

    文章目录 5.1 不要把玩具乱丢 5.2 Unity工程目录结构 5.3 Resources.Load实战测试 5.3.1 资源下载与导入 5.3.2 目录整理 5.3.3 代码动态加载资源 5.3. ...

  9. 【游戏开发创新】Unity+人工智能,让小朋友的画成真,六一儿童节一起来画猫猫吧(Unity | 人工智能 | 绘图 | 爬虫 | 猫妖)

    文章目录 一.前言 二.一起来画猫猫 三.爬虫,无穷只猫 四.猫猫作品展 五.Unity制作讲解 1.界面素材 2.UGUI制作界面 3.分辨率适配 4.如何检测鼠标事件 5.世界坐标转局部坐标 6. ...

  10. Unity从零开始构建能力体系 Unity Ability System

    从零开始构建能力体系 你会学到什么 如何实施能力体系 如何使用用户界面工具包创建用户界面 如何使用Unity的GraphView API 如何实现保存系统 MP4 |视频:h264,1280×720 ...

最新文章

  1. 自组织映射网络(SOM)如何解决TSP问题
  2. 计算机主板硬件术语,电脑硬件扫盲帖---主板术语详解
  3. Unity手游之路四3d旋转-四元数,欧拉角和变幻矩阵
  4. websocket 西部数码php_网页实时聊天之PHP实现websocket
  5. Oracle-(if/case/以及模拟注册登录)练习-20131015
  6. centos7配置mysql其他机器访问_CentOS7安装MySQL并开启远程访问详解
  7. 【HANA系列】SAP HANA Studio出现Fetching Children...问题
  8. Java BigDecimal类
  9. 路飞学城python开发ftp_路飞学城-Python开发集训-第一章
  10. 微型计算机软件系统分为什么,微型计算机软件微型计算机软件主要包括哪些软件?...
  11. js基本概念(上)之数据类型
  12. (弃更)一些黑科技和技巧
  13. 解决办法在idea中搭建spark环境:Unable to fetch table student. Invalid method name: ‘get_table_req‘;
  14. 权重衰减(L2正则化)的作用
  15. dSYM-如何获取dSYM UUID并快速定位到已发布程序的crash位置(二)
  16. 针对Matlab脑电数据EEG处理、 eeglab工具箱、Neuracle数据采集操作要点事项
  17. ORA-01732: 此视图的数据操纵操作非法
  18. RabbitMQ报错(2)——Message:Already closed: The AMQP operation was interrupted: AMQP close-reason, initia
  19. 三维计算机视觉(五)--特征描述子
  20. 红帽RHCE之DHCP

热门文章

  1. 用python解“计算工资”题
  2. COMMAND NOT SUPPORTED 解决方法
  3. 盘点4种常用的推荐算法
  4. VMware 8安装Mac OS X 10.7 Lion
  5. 测试空间大数据软件(Hadoop + HBase + GeoWave + GeoServer)
  6. 【好东西】ACM在线模版-f-zyj
  7. 南京财经的计算机科学与技术,2021年南京财经大学计算机科学与技术(081200)考研专业目录_硕士研究生考试范围 - 学途吧...
  8. 贵州大数据声势已起 如何引进人才?
  9. 观《怦然心动》之后的感悟
  10. Qt 实现画线笔锋效果详细原理