Unity 物理系统 -- 刚体简介

1,179 阅读4分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

刚体(RigidBody)

在Unity理引擎中,使用刚体(RigidBody)来模拟这种物理效果,当一个游戏对象被赋予刚体组件之后,游戏引擎就会对其进行物理效果的计算和模拟。同时我们也可以给这个对象施加各种作用力,让它运动起来。另外如果要实现重力的效果,那么相应的游戏物体都必须附上刚体组件。

组件的添加:在Inspector面板中->Add Component->Physics->Rigidbody

组件面板上的属性

  • Mass:质量。
    质量越大,惯性越大。建议场景中的物体质量最好不要相差100倍率以上。防止两个质量相差太大的物体碰撞后会产生过大的速度,从而影响游戏性能及呈现的效果。

  • Drag:阻力(摩擦力)。
    这里指的是空气阻力,属性数值影响阻碍此物体对象的直线运动的速度效果。当游戏物体受到某个作用力的时候,这个值越大越难移动。如果设置成无限的话,物体会立即停止移动。

  • Angular Drag:角阻力(旋转摩擦力)。
    同样指的是空气阻力,只不过是用来阻碍物体旋转的。如果设置成无限的话,物体会立即停止旋转。

  • Use Gravity:使用重力效果
    不勾选,则不会受到重力影响。

  • Is Kinematic:是否符合运动学的(是否受到物理引擎的驱动)。
    勾选后,变成不再受物理引擎的影响,改为受Transform的影响。即不再有重力,不再被碰撞等,只会呆在Transform规定的位置上不动,物体撞击时候像一堵墙一样不会倒,位置不会因碰撞而发生改变。

  • Interpolate:差值类型。
    如果看到刚体移动的时候运动的不是很平滑,可以选择一种平滑方式。即:平滑物体运动的曲线。
    None(无差值):不使用差值平滑。
    Interpolate(差值):根据上一帧来平滑移动。
    Extrapolate(推算):根据推算下一帧物体的位置来平滑移动。

  • Collision Detection 碰撞侦测。用来改变物体碰撞检测的精度。
    Discrete(离散):默认的碰撞检测方式。但若当物体A运动很快的时候,有可能前一帧还在B物体的前面,后一帧就在B物体后面了,这种情况下不会触发碰撞事件,所以如果需要检测这种情况,那就必须使用后两种检测方式。
    Continuous(连续):这种方式可以与有静态网格碰撞器的游戏对象进行碰撞检测。 可以避免因物体移动速度过快而穿过另一个物体的情况。
    Continuous Dynamic(动态连续):这种方式可以与所有设置了2或3方式的游戏对象进行碰撞检测。

  • Constraints:约束。
    约束位置或旋转时的x/y/z坐标,使其Freeze(冻结)。比如想控制游戏对象人物上台阶不会摔倒,或者高速碰到一个墙壁物体时不会胡乱转动的话,则要冻结x,y和z轴的旋转。

  • centerOfMass:相对于变换原点的质心。

  • angularVelocity 刚体的角速度向量,修改它可以使刚体进行旋转

注意:处理Rigidbody时,一般情况物理仿真需要用FixedUpdate代替Update。

代码添加力的方法:

  • AddForce 添加到刚体的力。
  • AddForceAtPosition 在position位置应用force力。作为结果这个将在这个物体上应用一个扭矩和力。
  • AddRelativeForce 添加力到刚体。相对于它的系统坐标。

Constant Force组件属性介绍

(依附于刚体组件存在)

  • Force:绝对力 世界坐标力。
  • Relative Force:相对力 自身坐标力。
  • Torque[tɔ:k] :绝对扭距 世界坐标扭距。
  • Relative Torque:相对扭距 自身坐标扭距。

相关函数:

  • 刚体睡眠(Sleep)和唤醒(WakeUp)函数
  • Sleep 使刚体睡眠,不进行移动。
  • WakeUp 使刚体能够运动。

通过刚体的速度向量(velocity)控制移动

示例

创建一个Cube,添加刚体组件,编写脚本,利用Rigidbody.velocity刚体的速度向量驱动物体运动,通过按空格键按下使物体向上运动。

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
	private Rigidbody rigidbody;
        
	void Start()
        {
		 //获取挂载物体上的RigidBody组件
		 this.rigidbody=this.GetComponent<RigidBody>();
	}
        
	void FixedUpdate()
        {
		if (Input.GetButtonDown("Jump"))  //按下空格键
                {
		  	//对刚体设置速度向量
			this.rigidbody.velocity = new Vector3(0, 10, 0);
                }
	}
}

AddExplosionForce 应用一个力到刚体来模拟爆炸效果。

API文档中的实例

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public float radius = 5.0F;
    public float power = 10.0F;

    void Start() 
    {
        Vector3 explosionPos = transform.position;
        Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
        foreach (Collider hit in colliders)
        {
            Rigidbody rb = hit.GetComponent<Rigidbody>();

            if (rb != null)
                rb.AddExplosionForce(power, explosionPos, radius, 3.0F);

        }
    }
}