Unity 3D里两个碰撞体之间发生碰撞可以用OnCollision族函数和OnTrigger族函数来获知和处理。Unity官方给出了两张可发生碰撞的组合表:

Collision detection occurs and messages are sent upon collision
  Static Collider Rigidbody Collider Kinematic 
Rigidbody Collider
Static 
Trigger Collider
Rigidbody 
Trigger Collider
Kinematic Rigidbody 
Trigger Collider
Static Collider   Y        
Rigidbody Collider Y Y Y      
Kinematic Rigidbody Collider   Y        
Static Trigger Collider            
Rigidbody Trigger Collider            
Kinematic Rigidbody Trigger Collider            
Trigger messages are sent upon collision
  Static Collider Rigidbody Collider Kinematic 
Rigidbody Collider
Static 
Trigger Collider
Rigidbody 
Trigger Collider
Kinematic Rigidbody 
Trigger Collider
Static Collider         Y Y
Rigidbody Collider       Y Y Y
Kinematic Rigidbody Collider       Y Y Y
Static Trigger Collider   Y Y   Y Y
Rigidbody Trigger Collider Y Y Y Y Y Y
Kinematic Rigidbody Trigger Collider Y Y Y Y Y Y

不过,生搬硬背显然不是一个有理想的死程应该做的事情。那么,要如何理解和记忆Unity 3D里的碰撞发生条件呢,归根结底只要理解了以下五个概念就搞定了:

Collider

Rigidbody

Static

Kinematic

Trigger

Collider——很简单,就是碰撞盒,有碰撞盒才有碰撞,所有碰撞的参与者都必须要有至少一个碰撞盒才行;

Rigidbody——刚体,当刚体存在时物理引擎就会介入,对于引擎来说,碰撞必须要有刚体参与(原因后述),但是并不要求碰撞的双方都是刚体,只要动的一方是刚体就OK,如果双方都有位移或者旋转,那么只要有一方是刚体就OK;

Static——这其实只是一个描述,或者说概念,任何不是刚体的物体,引擎都认为它永远是Static的,即静止的,哪怕它正在发生位移或者旋转;而刚体,引擎认为它是“能运动的”,也就是说,刚体虽然可以保持静止的状态,但是一旦发生位移或者旋转,引擎就会认为它动了;对于两个静止的物体,引擎认为他们不会发生碰撞,也就不会处理他们之间碰撞盒的任何交叠,这里包括两个非刚体,也包括一个保持静止的刚体和一个非刚体。这就是碰撞发生的双方中运动的那一方必须要是刚体的原因。

Kinemtic——这是一个描述,同时也是Rigidbody的一个属性。被标记为Kinematic的刚体就成为了一个纯运动学物体,这意味着它不再受外力作用,它的运动状态直接由位置和旋转来决定。当然,一个Kinematic的刚体还是可以对外产生作用力的,也就是说,它可以推动其他刚体,但是其他刚体对它无可奈何。

Trigger——这也是一个描述,同时是Collider的一个属性。被标记为Trigger的碰撞盒不再具备物理特性,这与Kinematic不一样,Kinematic的刚体仍就是一个物理体,而Trigger只代表一个区域,或是一个引子(这取决于它在碰撞中担当的角色,在碰撞中,如果它是运动的那一方,那么它就是一个引子,只要它碰撞到了任何物体,不论静止还是运动,都会被触发;如果它是静止的那一方,那么它就是一个区域,所有进入此区域的运动物体都会触发它,这里的“运动”不是单纯的位移或者旋转,参照Static的定义)。

好了,下面拿着这五个概念对照的看看Unity官方提供的表单。

先看Collision表,Collision是物理引擎管辖下的碰撞,即便是你不处理OnCollision族函数,物理引擎也会为碰撞双方计算作用力和作用力下的运行。由于Trigger标记下的物体不再是物理体,任何标记为Trigger的物体都不会触发Collision。物理碰撞的发生必然是有一方在运动,因此如果双方都被引擎认为是静止的物体,是不可能发生Collision的,因此双方都是非刚体(表中的Static Collider)时无法触发Collision。这里还有一个小问题,光从Collision表里是看不出来的,那就是在Static Collider和Rigidbody Collider之间,即便Collision表里画的是对钩,当碰撞里有位移或者旋转的那一方是Static Collider而不是Rigidbody Collider的时候,Collision是不会触发的哦,原因很简单,就是前面说的引擎认为物体静止的问题,没有位移或者旋转的Rigidbody是静止的,而非刚体也是静止的,两个静止的物体无法发生碰撞。至于Kinematic Rigidbody Collider,由于它本身不会受外力作用,而Collision是要能够产生物理作用力的,所以只有当能够受外力作用的物体跟它相撞时才会触发Collision,因此,没有作用力概念的Static Collider和不受外力作用的Kinematic Rigidbody Collider是无法跟它产生Collision的。

再看Trigger表,要触发Trigger就至少要有一个被标记为Trigger的碰撞盒存在,因此双方都没有被标记Trigger时,Trigger是不会触发的。即便有被标记为Trigger的物体存在,如果双方都被引擎认为是静止状态,同样不会触发Trigger(还是那个道理,两个被引擎认为静止的物体,是无法发生碰撞的),因此Static Collider跟Static Trigger Collider之间,两个Static Trigger Collider之间,都不会触发Trigger。跟Collision表一样,这里也有一个小问题光从表里看不出来,就是当Static Collider遇上Rigidbody(Kinematic)时,不管谁是Trigger,运动的一方必须要是Rigidbody(Kinematic)才能触发Trigger,道理同上。

唯一一个例外情况:

如果双方初始化在了一起,也就是说双方初始化出来碰撞盒就发生了交叠,这时候物理引擎网开一面,对于Collision来说,只要双方都不是Trigger,且有一方是非Kinematic的Rigidbody(也就是说Collision表里画了对钩的组合),就必然会发生一次Collision,对于Trigger来说,只要双方有一方是Trigger,且有一方是Rigidbody(Kinematic)(亚也就是Trigger表里画了对钩的组合),那么就必然会触发一次Trigger。当然这仅限初始化的那一帧,之后就一切回归正轨。

不过Unity 3D在这里有一个bug,当双方一个是非Kinematic的Rigidbody,另一方是Static Collider也就是非刚体,且碰撞盒在初始化时就交叠在了一起的话,除了一开始的那一帧会触发Collision外,之后刚体不动而非刚体动,仍有一定几率会触发Collision(按规则说是不能触发的),具体表现就是非刚体可以推着刚体走。

[Unity 3D] Unity 3D 里的碰撞检测的更多相关文章

  1. 关于Unity中的3D拾取

    3D拾取 3D游戏实际上看到的是2D画面,我们在屏幕上点击,想要找到哪个3D物体,我们实际上是在一个2维平面内做3D拾取. 3D拾取实际上是,当玩家点击屏幕的时候,会从显示屏幕的摄像头发射一条射线,射 ...

  2. 如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室(升级版)

    很长一段时间没有写3D库房,3D密集架相关的效果文章了,刚好最近有相关项目落地,索性总结一下 与之前我写的3D库房密集架文章<如何用webgl(three.js)搭建一个3D库房,3D密集架,3 ...

  3. webgl(three.js)实现室内三维定位,3D定位,3D楼宇bim、实时定位三维可视化解决方案——第十四课(定位升级版)

    序: 还是要抽出时间看书的,迷上了豆豆的作品,最近在看<天幕红尘>,书中主人公的人生价值观以及修为都是让我惊为叹止.很想成为那样的人,但是再看看自己每天干的事,与时间的支配情况,真是十分的 ...

  4. Ubuntu 11.10 安装GMONE3,卸载 UNITY和UNITY 2D

    Ubuntu 11.10安装GNOME3: 1)sudo apt-get install gnome-shell    sudo apt-get install gnome-themes*   (或者 ...

  5. [Unity][安卓]Unity和Android Studio 3.0 交互通讯(1)Android Studio 3.0 设置

    [安卓]Android Studio 3.0 JDK安卓环境配置(2017.10) http://blog.csdn.net/bulademian/article/details/78387052 [ ...

  6. Unity又称Unity Application Block

    本文关注以下方面(环境为VS2012..Net Framework 4.5以及Unity 3): Ioc/DI简介: Unity简单示例 一.Ioc/DI简介 IoC 即 Inversion of C ...

  7. 如何用webgl(three.js)搭建一个3D库房,3D密集架,3D档案室,-第二课

    闲话少叙,我们接着第一课继续讲(http://www.cnblogs.com/yeyunfei/p/7899613.html),很久没有做技术分享了.很多人问第二课有没有,我也是抽空写一下第二课. 第 ...

  8. Unity手册-Unity概述

    Unity概述 Unity是一个强大引擎,他自带的多种工具可以满足你多种需求. 这种编辑器是直观的可定制的,让你的工作更大的自由. 原文 Unity is a powerful engine with ...

  9. 教你调节Boom 3D的3D音效强度,让音乐更带感

    Boom 3D的专业3D环绕技术,让用户能全身心地沉浸在立体音效中.无论是聆听音乐,还是观赏电影,立体音效都能为人们带来更加真实的听觉感触. 那么,Boom 3D的3D环绕功能到底能给用户带来怎样的体 ...

  10. 如何用webgl(three.js)搭建一个3D库房,3D仓库,3D码头,3D集装箱可视化孪生系统——第十五课

    序 又是快两个月没写随笔了,长时间不总结项目,不锻炼文笔,一开篇,多少都会有些生疏,不知道如何开篇,如何写下去.有点江郎才尽,黔驴技穷的感觉. 写随笔,通常三步走,第一步,搭建框架,先把你要写的内容框 ...

随机推荐

  1. 对Devexpress ASP.NET组件的一些看法

    使用.net开发的应该都熟悉DevExpress这套组件,强大的功能,显著提高开发效率和提升用户体验. 不过好像大都用winform, 说起用asp.net组件来开发webform,很多人开口就说慢, ...

  2. HTML静态网页(框架)

    1.frameset frameset最外层,使用时需要去除body改用frameset. <frameset  rows="100,*" frameborder=" ...

  3. Android应用开发基础篇(5)-----Handler与多线程

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/19/2358155.html 一.概述 Handler这个类主要用来发送和处理消息的.它有多个发 ...

  4. android五种布局模式

    Android布局是应用界面开发的重要一环,在Android中,共有五种布局方式,分别是:LinearLayout (线性布局),FrameLayout(框架布局),AbsoluteLayout(绝对 ...

  5. 如何使用autotools生成Makefile

    安装autotools工具sudo apt-get install autoconf 一,四个代码文件init.s lcd.c addr.h uart.c 二,命令:autoscan 三,命令:vi ...

  6. MVC-03 控制器(5)

    八.动作过滤器 有时在运行Action之前或之后会需要运行一些逻辑运算,以及处理一些运行过程中所生成的异常状况,为了满足这个需求,ASP.NET MVC提供动作过滤器(Action Filter)来处 ...

  7. C++模板:二分图匹配

    int Dfs(int k){ for(int i=0;i<v[k].size();i++){ int a=v[k][i]; if(used[a]==0){ used[a]=1; if(link ...

  8. HDU 1108 最小公倍数

    #include <cstdio> int gcd(int a,int b) { ) return a; else return gcd(b,a%b); } int main() { in ...

  9. 如何在自己的Activity中去控制EditText的焦点

    在进入一个Activity时,如果这个Activity中有EditText,则这个EditText会自动获取焦点,然后就会弹出软键盘,这样给用户体验不是很好.所以一般会通过代码控制让EditText不 ...

  10. 赵雅智:service_startService生命周期

    案例演示 布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...