Rigidbody类,这个常用类是用于Unity模拟物理碰撞的,经常使用,比较重要所有,下面详细的描述Rigidbody的组件,以及该类的属性和方法!
一.Rigidbody Compents:
Mass: 用于设置游戏对象中的质量,单位为千克,默认为1kg
Drag: 游戏对象受力运动时所受到的空气的阻力,当为0时,表示没有空气助力。
设置的值越大,空气阻力越大,当值大到一个临界值,物体将停止运动
Angular Drag: 游戏对象受扭矩力旋转时受到的控制阻力。当为0时,代表没有空气阻力
阻力极大时游戏对象会立即停止旋转。
Use Gravity: 是否使用重力,勾选后该物体将会受到重力影响
Is Kinematic: 如果勾选,则该游戏对象不会受物理引擎的游戏,只能通过Transform组件进行操作
这对于移动平台或者如果要为附加了HingeJoint(铰链关节)的Rigidbody设置动画非常有用
Interpolate: 该选项是一个枚举类型,作用是插值,
None: 不使用插值
Interpolate:根据上一帧的Transform进行平滑插值
Extrapolate:根据估算的下一帧的Transform进行平滑插值
Collision Detection: 该属性用于防止快速移动的对象在没有检测到碰撞下穿过其他对象而未发生碰撞。
Discrete:离散碰撞检测,默认值,会对场景中所有的碰撞器使用离散碰撞检测
但是在离散式的碰撞检测中,当物体高速连续的运动时,该选项便
检测到物体碰撞,因为速度太快,采用的是离散碰撞检测,
一般用于检测低速移动或者静态物体的碰撞,较销毁性能
Continuous: 连续碰撞检测,该模式用于动态碰撞器(带有Rigidbody)使用连续碰撞模式
来检测与带有Collidr的物体进行碰撞,如果其他刚体设置为了ContinuousDynamic,
会使用连续检测和这个刚体进行碰撞检测,该选项用于需要采用连续
碰撞检测快速运动的物体,该模式很销毁性能,
Continuous Dynamic: 连续动态碰撞检测,该模式采用了连续且动态的碰撞模式,如果与之碰撞的游戏物体
是Continuous或者Continuous Dynamic模式,与这个物体碰撞则会和这个刚体进行
连续碰撞检测,当然也会和静态的Collider使用连续检测,但是对于其他的Collider
例如模式为(Discrete的刚体)就会采用离散检测。一般用于检测快速动态的游戏物体
Continuous Speculative: 使用推测式连续碰撞检测,这是唯一的CDD模式,CDD模式能够确保快速的移动
的物体与物体进行碰撞,而不是穿过这样物体,Unity提供了两种CCD方法。
具体的CDD模式本节不具体的阐述,留着下一节专门讨论一下这个CDD模式
Constraints: 刚体运动的约束,包括位置约束和旋转约束,勾选表示在该坐标上不允许进行此类操作
Freeze Position: 停止刚体在X轴、Y轴和Z轴上的运动
Freeze Rotation:停止刚体绕局部X轴、Y轴和Z轴选择性旋转。
二.Rigidbody Properities:
inertiaTensor: 此属性用于设置刚体的惯性张量,在距离重心同等的条件下,刚体会向张量值小的一边切斜
例如m_Rigidbody.inertiaTensor = new Vector3(15.0f,10.0f,1.0f);
则刚体会向y轴倾斜,反之亦然,当张量相同的时候,那就是随机在各轴方向倾斜
public class RigidbodyInertiaTensor : MonoBehaviour
{
private Rigidbody m_Rigidbody;
void Start()
{
m_Rigidbody = gameObject.GetComponent<Rigidbody>();
}
private void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 200, 45), "y轴的惯性张量小于x轴"))
{
transform.position = new Vector3(0,4,0);
//让自身绕z轴旋转45度
transform.rotation = Quaternion.Euler(0,0,45);
//设置Rigidbody的惯性张量
m_Rigidbody.inertiaTensor = new Vector3(15.0f,10.0f,1.0f);
}
if (GUI.Button(new Rect(10, 60, 200, 45), "x轴的惯性张量小于y轴"))
{
transform.position = new Vector3(0,4,0);
//让自身绕z轴旋转45度
transform.rotation = Quaternion.Euler(0,0,45);
//设置Rigidbody的惯性张量
m_Rigidbody.inertiaTensor = new Vector3(5.0f,10.0f,1.0f);
}
if (GUI.Button(new Rect(10, 110, 200, 45), "y轴的惯性张量与x轴相同"))
{
transform.position = new Vector3(0,4,0);
//让自身绕z轴旋转45度
transform.rotation = Quaternion.Euler(0,0,45);
//设置Rigidbody的惯性张量
m_Rigidbody.inertiaTensor = new Vector3(10.0f,10.0f,1.0f);
}
}
}
mass:该属性用于设置或者返回刚体的质量,一般情况下,刚体质量在0.1左右模拟最佳,最大最好不要超过10
否则容易出现不稳定的情况,对于自由落体运动,物体的速度只与重力加速度和空气阻力Drug有关
与质量无关,mass的主要作用是在物体发生碰撞计算碰撞后物体的速度,当一个物体的分别去撞击mass大和mass小的物体
根据动量守恒定律,重的物体被撞击后的速度要慢与较轻的物体,代码示例如下:
public class RigidbodyMass : MonoBehaviour
{
public Rigidbody r1,r2,r3,r4,r5;
Vector3 v3 = Vector3.zero;
void Start()
{
r1.mass = 0.1f;
r2.mass = 5.0f;
r3.mass = 2.0f;
r4.mass = 0.1f;
r5.mass = 4.0f;
r3.useGravity = false;
r4.useGravity = false;
r5.useGravity = false;
v3 = r3.position;
}
private void FixedUpdate()
{
Debug.Log(Time.time +" "+ "R1的速度=" + r1.velocity);
Debug.Log(Time.time +" "+ "R2的速度=" + r2.velocity);
Debug.Log(Time.time +" "+ "R3的速度=" + r3.velocity);
Debug.Log(Time.time +" "+"R4的速度=" + r4.velocity);
Debug.Log(Time.time +" "+ "R5的速度=" + r5.velocity);
}
private void OnGUI() {
if(GUI.Button(new Rect(10,10,200,45),"用R3撞R4"))
{
r3.position = v3;
r3.rotation = Quaternion.identity;
r3.velocity = new Vector3(0,0,4);
}
if(GUI.Button(new Rect(10,60,200,45),"用R3撞R5"))
{
r3.position = v3;
r3.rotation = Quaternion.identity;
r3.velocity = new Vector3(0,0,4);
}
}
}
velocity: 该属性用于返回或者设置刚体的速度 ,单位是米/每秒
在脚本中无论是给刚体赋予一个Vector3类型的向量,还是获取当前刚体的速度,都是相当世界坐标系
public class RigidbodyVelocity : MonoBehaviour
{
public Rigidbody A,B;
void Start()
{
A.velocity = new Vector3(0,0,-15.0f);
B.velocity = new Vector3(0,0,10.0f);
}
private void OnGUI()
{
GUI.Label(new Rect(10, 10, 300, 45), "A物体当前的速度为:" + A.velocity);
GUI.Label(new Rect(10, 60, 300, 45), "B物体当前的速度为:" + B.velocity);
Debug.Log("A物体当前的速度为:" + A.velocity);
Debug.Log("B物体当前的速度为:" + B.velocity);
}
}