【Unity】物理碰撞实验
这几天为了准备面试,所以决定对平时学习中的盲点扫盲一下,首先想到的就是物理碰撞。以前没有好好研究过,一直模糊不清,到底什么条件下才可以产生物理碰撞呢?只要其中一个有Rigidbody就可以了吗?所以进行了下面的实验。
以下内容参考了Unity圣典的组件手册。
----------------------------------------------------------------------------分割线--------------------------------------------------------------------------------
首先查找资料,发现Unity组件文档中将碰撞体分为了3个类型,如下所示。
Static Collider 静态碰撞器
These are GameObjects that do not have a Rigidbody attached, but do have a Collider attached. These objects should remain still, or move very little. These work great for your environment geometry. They will not move if a Rigidbody collides with them.
指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或者很轻微的移动。对于环境模型十分好用,当和刚体碰撞时而不会移动。
Rigidbody Collider 刚体碰撞器
These GameObjects contain both a Rigidbody and a Collider. They are completely affected by the physics engine through scripted forces and collisions. They might collide with a GameObject that only contains a Collider. These will likely be your primary type of Collider in games that use physics.
指的是同时附加了刚体和碰撞器的游戏对象。通过脚本的力量和碰撞完全受物理引擎的影响。可以和只包含碰撞器的游戏对象碰撞。将会成为你游戏中使用物理效果的基本类型碰撞器。
Kinematic Rigidbody Collider 运动学刚体碰撞器
This GameObject contains a Collider and a Rigidbody which is marked IsKinematic. To move this GameObject, you modify its Transform Component, rather than applying forces. They're similar to Static Colliders but will work better when you want to move the Collider around frequently. There are some other specialized scenarios for using this GameObject.
指的是同时包含碰撞器和刚体,并且激活IsKinematic的一类游戏对象,要移动这类游戏对象,要修改它的Transform组件(指的是position和rotation这类属性),而不是用力。它们很像静态碰撞器,不过如果你想要不停地到处移动碰撞器,它们会更好用。这类游戏对象还有许多其他的独特使用情景。
运动学刚体碰撞器是个非常懒惰和霸道的家伙,它碰到其他碰撞器完全没有反应(其实还是有点反应,会触发一些碰撞函数的,后面有解释)。它不受力、重力或扭矩的影响。可以通过设置Transform 的position和rotation来准确的操作它们或者让它们动起来,但是,它们可以和其他的非运动学刚体互相作用。对于放在运动学刚体碰撞器上面的刚体,会受到运动学刚体施加的摩擦力。
还有一类叫做角色控制器。
Character Controllers 角色控制器
You use Character Controllers if you want to make a humanoid character. This could be the main character in a third person platformer, FPS shooter or any enemy characters.
如果想制作一个类似人的角色那就使用角色控制器。这可以是第三人称平台游戏、第一人称射击游戏的主要角色或任何敌对角色。
These Controllers don't follow the rules of physics since it will not feel right (in Doom you run 90 miles per hour, come to halt in one frame and turn on a dime). Instead, a Character Controller performs collision detection to make sure your characters can slide along walls, walk up and down stairs, etc.
这类控制器不遵循物理规则因此它感觉上不对劲(在Doom中,你跑到了90英里每小时,然后马上停下而且可以极快的转身)。不过,角色控制器执行碰撞检测以保证你的角色可以沿着墙滑动,上下台阶等等。
Character Controllers are not affected by forces but they can push Rigidbodies by applying forces to them from a script. Usually, all humanoid characters are implemented using Character Controllers.
角色控制器不受力影响(但是重力效果还是有的)但是可以被由代码施加的力推动。通常,所有类似人的角色都用角色控制器来执行。
Character Controllers are inherently unphysical, thus if you want to apply real physics - Swing on ropes, get pushed by big rocks - to your character you have to use a Rigidbody, this will let you use joints and forces on your character. Character Controllers are always aligned along the Y axis, so you also need to use a Rigidbody if your character needs to be able to change orientation in space (for example under a changing gravity). However, be aware that tuning a Rigidbody to feel right for a character is hard due to the unphysical way in which game characters are expected to behave. Another difference is that Character Controllers can slide smoothly over steps of a specified height, while Rigidbodies will not.
角色控制器本身不具物理特性,因此如果想应用真正的物理作用——在绳上摇摆,被大石头推动——到你的角色,必须用刚体,这会允许你把铰链或力用到你的角色上。角色控制器永远沿Y轴对齐,因此,如果你的角色需要在空间中改变方向那也必须用到刚体(比如在变化的引力控制下)。但是,要意识到调整一个刚体在角色上表现自然是很难的,因为游戏角色自身的非物理特性总想表现出来。另一个困难是,角色控制器可以从特定高度的台阶上平滑地滑下,而刚体不会。
The Controller does not react to forces on its own and it does not automatically push Rigidbodies away.
控制器不会对加在它自身上的力做出反应,也不会自动推开其他刚体。(这里我没有明白,因为我实验过在一个刚体内部实例化一个控制器,刚体是会被弹开的。如果有人懂请告诉我,不胜感激!)
If you want to push Rigidbodies or objects with the Character Controller, you can apply forces to any object that it collides with via the OnControllerColliderHit() function through scripting.
如果想让角色控制器推开其他刚体或者对象,你可以在对象附加的脚本中添加OnControllerColliderHit()函数,这样对它们施加力就能够产生碰撞。
也就是说,角色控制器可以使用物理效果影响其他对象,前提是你自己写了脚本。
On the other hand, if you want your player character to be affected by physics then you might be better off using a Rigidbody instead of the Character Controller.
而角色控制器不能通过物理效果被其他对象影响。因此,如果你想让你的游戏角色被物理效果影响,那就最好使用刚体而不是角色控制器。
角色控制器和运动学刚体有点像,因为它们都不受力的作用(运动学刚体更像是一个刚体,只是不会受到其他任何外力的影响,就像是古代的国王,虽然和普通平民一样都是人,但是只能他欺负别人,别人无法欺负他;而角色控制器本身就不具有物理特性,不可以推开别人(除非写了自己的脚本),也不会被别人影响,只是它可以执行碰撞检测)。但是也有几点不同的地方。首先,运动学刚体是无法通过代码施加力的作用来推动,但是角色控制器是可以的。第二,运动学刚体不会受到重力的作用,而角色控制器是有重力效果的。其次,角色控制器只能沿Y轴旋转,也就是人永远都是直立状态,不会因为受到力的作用就趴下啦,而刚体是可以的。第三,角色控制器可以从特定高度台阶上平滑地滑下,而刚体不会。
说了这么多,晕了吧,恩,我也晕了。所以我们来做下实验!我们通过一个最简单的场景,即一个平行光、一个平面、两个正方体来试验一下。通过给两个正方体添加不同的碰撞体类型来观察是否会发生碰撞。
下面的实验中,一个正方体保持静止,另一个正方体我们通过代码来控制运动,即上下左右方向键可以控制它的上下左右运动。
移动的静态碰撞器VS静止的静态碰撞器
移动的静态碰撞器VS静止的刚体碰撞器
- 被施加了外力,也就是说在代码里使用了AddForce;
- 刚体的属性发生了变化;
- 和它通过关节连接的刚体发生了移动,因为连带关系,所以它也被唤醒了;
- 被其他刚体碰撞器碰撞。但是,只有处于运动状态中的刚体(包括普通的刚体碰撞器和运动学刚体碰撞器)能唤醒休眠中的刚体,静态碰撞器不能唤醒休眠中的刚体。即如果你将一个静态碰撞器(没有和任何刚体绑定过)绑定到处于休眠中的刚体,或者将静态碰撞器抽离处于休眠中的刚体时,这个休眠中的刚体是不会被唤醒的。但是如果你将一个运动中的刚体从它所属的且处于休眠状态中的顶层刚体移出时,处于休眠中的刚体将会被唤醒,且会在图形更新里被重新正确的计算。
移动的刚体碰撞器VS静止的静态碰撞器
移动的刚体碰撞器VS静止的刚体碰撞器
移动的静态碰撞器VS静止的运动学刚体碰撞器
移动的运动学刚体碰撞器VS静止的静态碰撞器
移动的运动学刚体碰撞器VS静止的刚体碰撞器
移动的刚体碰撞器VS静止的运动学刚体碰撞器
移动的运动学刚体碰撞器VS静止的运动学刚体碰撞器
移动的静态碰撞器VS静止的角色控制器
移动的刚体碰撞器VS静止的角色控制器
移动的运动学刚体碰撞器VS静止的角色控制器
移动的角色控制器VS静止的静态碰撞器
移动的角色控制器VS静止的刚体碰撞器
移动的角色控制器VS静止的运动学刚体碰撞器
碰撞信息和触发信息
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 |