关于Rigidbody,Collider和CharacterController三者之间的关系和用法的总结

Rigidbody:多用在“物体”上,因为“物体”都是“死”的,他们的运动一般都是靠物理系统。所以对于Rigidbody的移动,不要用Translate(),要用各种“力”, 比如:Rigidbody的AddForce()方法,通过“力”来让它移动。另外,Rigidbody可以和NavMeshObstacle合用,因为后者也是用在“物”上的,但是一般不要和NavMeshAgent合用,因为这两个都会控制物体的运动,这样会有race condition。如果非要合用,请勾选Is Kinematic,由此看来如果Rigidbody的Is Kinematic属性被勾选了,那么Rigidbody就可以和任何其他的Component合用了,比如:NavMeshAgent,CharacterController。

Collider:定义了一个物体的形状,而我们的碰撞检测就是根据这个形状来进行的,随意Collider是碰撞检测的基础,几乎Unity中所有的物体都需要Collider。就算我们使用CharacterController一般会删掉原来的Collider,不过CharacterController本身自带了一个Capsule Collider。Collider分为static collider和dynamic collider,前者表示没有Rigidbody的collider,后者表示有Rigidbody的collider,static collider的物体最好是静止的物体,不要通过改变他的transform的position来使它运动,这样不仅会给物理引擎造成很多性能损失,而且会产生一些无法预测的行为。所以如果我们非要一个有collider的物体通过我们的脚本(比如通过Translate()方法)移动,并且不希望被物理引擎控制,那么我们需要给这个collider配上一个勾选了Is Kinematic的Rigidbody。因为Rigidbody的Is Kinematic就是让这个Rigidbody不受物理引擎的控制。结论:在游戏中,对于那些可能将来会移动的物体,我们不仅要加Collider,还要加上Rigidbody,如果希望是被物理引擎控制,就不勾选Rigidbody的Is Kinematic,如果希望不被物理引擎控制,希望通过自己的代码或者动画来控制,就勾选Rigidbody的Is Kinematic,而且这个属性还可以在脚本中随时改变,从而实现“ragdoll effect”,“ragdoll effect”类似于CS里面的效果,大部分时间物体的运动是通过脚本和动画控制的,如果遇到爆炸等,物体的运动就可以被物理系统接管了,这个时候开启Is Kinematic最合适了。

CharacterController:多用在“角色”上,因为“角色”多是“活”的(比如:游戏中的主角,NPC什么的),他们的运动要么是玩家控制,要么是脚本控制,所以一般不需要由物理系统来控制,如果由物理系统控制,反而使得游戏的操作性下降了。由玩家控制的“角色”肯定不要用Rigidbody,要用CharacterController。如果NPC非要用Rigidbody,那么请勾选Is Kinematic。使用了CharacterController以后,就不要用Translate()来移动物体了,要用它自己提供的Move()方法来移动物体。否则会有一些“诡异”的问题。

CharacterController不对任何“力”产生作用,同时也不对然和物体施加“力”,即使那个物体是Rigidbody。

Rigidbody会对“力”产生响应,如果一个物体加上了Rigidbody,首先会直接对“重力”产生响应,如果再加上Collider,就会对其他“力”产生响应了。同时如果使用Translate()移动Rigidbody,那么它会对其他的Rigidbody在碰撞的时候自动施加一个“力”。



Collider中Is Trigger的优先级高于Rigidbody(不管这个被标记为Is Trigger的Collider和Rigidbody是不是在同一个GameObject上)。因为Rigidbody是根据Collider来进行物理模拟的,Collider是Rigidbody的基础,所以如果这个Collider是Trigger,由于Trigger只是通过调用OnTrigger*()函数来响应碰撞这个行为,而不会去响应任何实质性的碰撞(所谓的实质碰撞,就是能被观察到的碰撞,比如碰撞之后产生运动,碰撞之后阻止物体穿过等等)。所以就算Rigidbody在,也发挥不了作用(OnCollision*()函数不会调用,同时也不会产生物理运动,也不会阻止物体穿过,反正任何可见的碰撞效果都没有)。

同理,Collider中Is Trigger的优先级也高于CharacterController,不过Collider和CharacterController一般不放在一起,所以这里指的是对方的物体上Collider的Is Trigger。

CharacterController(不要再加Collider,CharacterController有自带的Capsule Collider。并且使用Move()方法移动物体) 
用CharacterController去碰撞另一个物体,如果被碰撞的物体有Collider,并且Is Trigger没有勾选,那么无论这个物体是不是Rigidbody,CharacterController都会被这个物体“挡”下来,并且只会触发他自己的OnControllerColliderHit()这个回调函数(也就是说,如果被碰撞的物体或者它自己有OnTrigger*(),OnCollision*()这种函数,都不会被触发)。

所以如果我们想要实现一个CharacterController推箱子的游戏,那么首先这个箱子必须是Rigidbody,并且Collider不是Is Trigger,而这个“推力”需要在CharacterController的OnControllerColliderHit()这个函数中“发出”了。

如果被碰撞的物体Collider的Is Trigger方法勾选了,那么由于Is Trigger只是将Collider当成了一个“触发器”,而不会响应如何的实质碰撞(所谓的实质碰撞,就是能被观察到的碰撞,比如碰撞之后产生运动,碰撞之后阻止物体穿过等等),所以CharacterController会穿过被碰撞的物体,并且OnControllerColliderHit()这个回调不会起作用,取而代之的是双方的OnTrigger*()函数会被调用。

Rigidbody(如果勾选了Is Kinematic,那么这个Rigidbody就不受物理引擎控制了) 
一个物体一旦加上了Rigidbody,那么就可以立刻受到“重力”的影响,如果再加上Collider,那么就可以受到别的“力”的影响,由于Collider的Is Trigger的优先级较高,所以,如果Collider是Is Trigger(不管这个Is Trigger的Collider是不是和Rigidbody在一个物体上,反正只要碰撞双方出现了Is Trigger),那么这个Rigidbody就不会产生实质性的碰撞(所谓的实质碰撞,就是能被观察到的碰撞,比如碰撞之后产生运动,碰撞之后阻止物体穿过等等)。并且OnTrigger*()被调用,而不是OnCollision*()。

关于Rigidbody的OnCollision*()回调被调用的补充说明(来自:https://docs.unity3d.com/Manual/CollidersOverview.html): 
With normal, non-trigger collisions, there is an additional detail that at least one of the objects involved must have a non-kinematic Rigidbody (ie, Is Kinematic must be switched off). If both objects are kinematic Rigidbodies then OnCollisionEnter, etc, will not be called. With trigger collisions, this restriction doesn’t apply and so both kinematic and non-kinematic Rigidbodies will prompt a call to OnTriggerEnter when they enter a trigger collider.

Rigidbody:OnCollisionEnter(Collision c), OnCollisionStay(Collision c), OnCollisionExit(Collision c)

Collider Is Trigger: OnTriggerEnter(Collider c), OnTriggerStay(Collider c), OnTriggerExit(Collider c)

CharacterController: OnControllerColliderHit(ControllerColliderHit c)

产生碰撞(可以看见效果的碰撞或者像Is Trigger的Collider那样不可见效果的碰撞)的一般条件(不是必要条件,因为有一个例外,见后面的解释)是碰撞双方都要有Collider(不管是否是Is Trigger),并且其中至少有一个有Rigidbody或者CharacterController。这个时候碰撞产生,并且调用相应的回调函数。如果出现多个函数都可以调用的情况,看下面的优先级。

最高优先级:有Is Trigger的Collider参与的碰撞只会调用双方的OnTrigger*()函数,且不会产生实质碰撞(所谓的实质碰撞,就是能被观察到的碰撞,比如碰撞之后产生运动,碰撞之后阻止物体穿过等等)。

次高优先级:有CharacterController参与且没有Is Trigger的碰撞只会调用CharacterController的(如果被碰撞的也是CharacterController,那么他的OnControllerColliderHit()也会被调用)OnControllerColliderHit()函数。且会产生CharacterController被物体“档”下来的效果,不过除此之外没有其他任何物理效果。

最低优先级:有Rigidbody参与的碰撞,并且没有CharacterController和Is Trigger的Collider,会调用碰撞双方的OnCollision*()回调,并且由物理系统模拟碰撞之后的物理运动。

关于Rigidbody的OnCollision*()回调被调用的补充说明(来自:https://docs.unity3d.com/Manual/CollidersOverview.html): 
With normal, non-trigger collisions, there is an additional detail that at least one of the objects involved must have a non-kinematic Rigidbody (ie, Is Kinematic must be switched off). If both objects are kinematic Rigidbodies then OnCollisionEnter, etc, will not be called. With trigger collisions, this restriction doesn’t apply and so both kinematic and non-kinematic Rigidbodies will prompt a call to OnTriggerEnter when they enter a trigger collider.

为何Collider的Is Trigger的优先级最高?因为Collider是一切碰撞的基础。

例外:如果一个运动的物体A(通过改变Transform来使得它运动)和静止的物体B发生碰撞,A只有Collider,并且不是Is Trigger,B是Rigidbody,并且Collider也不是Is Trigger,那么任何回调函数都不回被触发,并且没有物理模拟碰撞效果,A会穿过B。但是如果A和B都是静止的,并且也开始就“挨着”,那么这个时候又会发生碰撞了,由于没有Is Trigger,所以是双方的OnCollisionEnter()被调用。

这个例外在官方文档被称为fail to sleep: 
https://docs.unity3d.com/Manual/RigidbodiesOverview.html 中关于Sleeping的第二段。

在官方文档中提到了static collider,所谓static collider,就是那些不和Rigidbody一起使用的Collider(相反的,那些和Rigidbody一起使用的Collider就叫做dynamic collider)。这些Collider一般用在静止的物体上,不要试图去直接改变他们Transform的position(不要使用Translate()方法或者直接给position赋值),因为这样会对物理引擎造成很大的性能影响。(参见:https://docs.unity3d.com/Manual/CollidersOverview.html)。CharacterController是没有额外加Collider的,而NavMeshAgent的运动是由Navigation System来掌管的,也不是属于我们说的情况。

拓展阅读(非常重要): 
https://docs.unity3d.com/Manual/CollidersOverview.html

原文地址:https://www.cnblogs.com/mcyushao/p/9653020.html

时间: 2024-10-01 04:46:44

关于Rigidbody,Collider和CharacterController三者之间的关系和用法的总结的相关文章

甲方、乙方、监理三者之间的关系及其在项目管理过程中的若干事项

1.甲方.乙方.监理三者之间的关系 甲方是工程项目的投资单位和受方单位,乙方是工程项目的承建单位和供方单位,监理是工程项目的监管单位和第三方单位.广义方面来讲,监理也属于乙方的范畴,是服务的提供者.从合同角度来讲,甲方与监理.甲方与乙方存在合同关系. 甲方与监理的合同关系:甲方根据合同委托和授权监理就工程项目的质量控制.进度控制.投资控制.信息管理.合同管理.安全管理.组织协调工作进行监理,监理在工程项目建设期间完成合同约定的上述工作内容. 甲方与乙方的合同关系:甲方根据合同委托和要求乙方就工程

电脑结构和CPU、内存、硬盘三者之间的关系

前面提到了,电脑之父——冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器. 我们看一下现在我们电脑的: 键盘鼠标.显示器.机箱.音响等等. 这里显示器为比较老的CRT显示器,现在一般都成功了液晶显示器. 我们想一下,我们在玩电脑的时候,我们使用键盘鼠标来操作电脑,我们在和其他人QQ聊天的时候,鼠标可以帮我们选中聊天的人,打开聊天窗口,键盘则是负责打字,帮我们输入聊天的内容. 我们在操作键盘鼠标的时候,其实都是在告诉电脑来做什么的.我们管键盘和鼠标叫输入设备. 输入设备

求解?表空间,表,用户这三者之间的 关系与区别?

发表于: 2012-02-11 16:40:58 小弟初学oracle,但是在表空间,用户,表这三者之间的关系,有点模糊,希望大牛指导下! 更多0分享到:       对我有用[0] 丢个板砖[0] 引用 | 举报| 管理 回复次数:21 关注 dengnanyi 一棵老松树 本版等级: #1 得分:0回复于: 2012-02-11 16:55:59 表空间:一个数据库划分为一个或多个逻辑单位,该逻辑单位称为表空间(TABLESPACE).一个表空间可将相关的逻辑结构组合在一起.表:表(tabl

Window系统、主函数和窗体函数这三者之间的关系

理解Window系统.主窗体.窗体函数这三者之间的关系,对于编写Windows程序十分重要. 主函数和窗体函数都是由Windows系统来调用的函数.仅仅只是主函数是程序启动之后.系统首先调用的函数: 而窗体函数是主函数在获得消息并把消息发给系统之后,由操作系统调用的函数. 不同的消息所相应的操作就是由窗体函数完毕的,Windows程序猿的工作就是编写窗体函数的case中的代码. Windows系统.主函数.窗体函数这三者之间的关系,例如以下图所看到的:

Window系统、主函数和窗口函数这三者之间的关系

理解Window系统.主窗口.窗口函数这三者之间的关系,对于编写Windows程序十分重要. 主函数和窗口函数都是由Windows系统来调用的函数,只不过主函数是程序启动之后,系统首先调用的函数: 而窗口函数是主函数在获得消息并把消息发给系统之后,由操作系统调用的函数. 不同的消息所对应的操作就是由窗口函数完成的,Windows程序员的工作就是编写窗口函数的case中的代码. Windows系统.主函数.窗口函数这三者之间的关系,如下图所示: Window系统.主函数和窗口函数这三者之间的关系

计算机组成和CPU、内存、硬盘三者之间的关系

电脑之父--冯·诺伊曼 提出了组成计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器. 来看一下现在我们电脑的:键盘鼠标.显示器.机箱.音响等等. 这里显示器为比较老的CRT显示器,现在一般都成功了液晶显示器. 回想一下,在玩电脑的时候,我们使用键盘鼠标来操作电脑,在和其他人QQ聊天的时候,鼠标可以帮我们选中聊天的人,打开聊天窗口,键盘则是负责打字,帮我们输入聊天的内容. 在操作键盘鼠标的时候,其实都是在告诉电脑来做什么的.我们管键盘和鼠标叫输入设备. 输入设备: 向电脑输入数据和信息

正确理解 AsyncTask,Looper,Handler三者之间的关系(基于android 4.0)

Looper 和Handler 是理解好AsyncTask的一个基础,我们可以先从这里开始,先给出一个主线程和子线程互相通信的例子. 1 package com.example.loopertest; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.Looper; 7 import android.os.Message; 8

CP/IP,SPDY,WebSocket 三者之间的关系

按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP是应用层的协议.在这三者之间,SPDY和WebSocket都是与HTTP相关的协议,而TCP是HTTP底层的协议.一.HTTP的不足 HTTP协议经过多年的使用,发现了一些不足,主要是性能方面的,包括:HTTP的连接问题,HTTP客户端和服务器之间的交互是采用请求/应答模式,在客户端请求时,会建立一个HTTP连接,然后发送请求消息,服务端给出应答消息,然后连接就关闭了.(后来的HTTP1.1支持持久连接)因为TCP连接的建立

jdk、jre、jvm三者之间的关系与区别

三者之间存在包含关系 JVM + 核心类库 = JRE JRE + java开发工具(javac.exe/jar.exe) = JDK 什么是JVM? Java Virtual Machine 即Java虚拟机 我们知道Java语言有一个独特的优点就是可以跨平台 像其它语言,比如C,我们要针对不同操作系统windos,mac……各出一套应用程序 而Java则可以做到一个软件在任何的操作系统中都能执行,这就是JVM的功劳. 本来我们编写的Java代码计算机还是不认识的,但是我们在每一个操作系统上都