一、剛體 Rigid Body
? 剛體利用體積(碰撞器 Collider)進(jìn)行碰撞計(jì)算,模擬真實(shí)的碰撞效果,產(chǎn)生力的作用

? 碰撞產(chǎn)生的必要條件:
- 兩個(gè)物體都有碰撞器 Collider
- 至少一個(gè)物體有剛體
-
Mass:質(zhì)量
默認(rèn)為千克,質(zhì)量越大慣性越大
-
Drag:空氣阻力
根據(jù)力移動(dòng)對(duì)象時(shí)影響空氣阻力大小
0 表示沒(méi)有空氣阻力
-
Augular Drag:旋轉(zhuǎn)阻力
根據(jù)扭矩旋轉(zhuǎn)對(duì)象時(shí)影響對(duì)象的空氣阻力大小
0 表示沒(méi)有阻力
-
Use Gravity:是否受重力影響
-
Is Kinematic:是否設(shè)置為運(yùn)動(dòng)學(xué)
如果啟用,對(duì)象將不會(huì)被物理引擎驅(qū)動(dòng),只能通過(guò) Transform 對(duì)其進(jìn)行操作
對(duì)于移動(dòng)平臺(tái),或者如果要?jiǎng)赢?huà)附加了 HingeJoint 的剛體,此屬性將非常有用
-
Interpolate:插值運(yùn)算
-
None:不應(yīng)用插值運(yùn)算
-
Interpolate:根據(jù)前一幀的變換來(lái)平滑變換
-
Extrapolate:插值運(yùn)算
根據(jù)下一幀的估計(jì)變換來(lái)平滑變換,若物理幀時(shí)間過(guò)長(zhǎng),此效果將不好
-
-
Collison Detection:碰撞檢測(cè)模式
-
Discrete:離散檢測(cè)
對(duì)場(chǎng)景中的所有其他碰撞體使用離散碰撞檢測(cè),其他碰撞體在測(cè)試碰撞時(shí)會(huì)使用離散檢測(cè)。
用于正常碰撞(默認(rèn)值)
-
Continuous:連續(xù)檢測(cè)
對(duì)動(dòng)態(tài)碰撞體(具有剛體)使用離散碰撞檢測(cè)
對(duì)靜態(tài)碰撞體(沒(méi)有剛體)使用連續(xù)碰撞檢測(cè)
設(shè)置為連續(xù)動(dòng)態(tài)的剛體,將在測(cè)試與該剛體的碰撞時(shí)使用連續(xù)碰撞檢測(cè)(物理性能消耗較大,物體運(yùn)動(dòng)緩慢時(shí)請(qǐng)?jiān)O(shè)置為 Discrete)
其他剛體將使用離散碰撞檢測(cè)
-
Continuous Dynamic:連續(xù)動(dòng)態(tài)檢測(cè)
對(duì)設(shè)置為連續(xù)和連續(xù)動(dòng)態(tài)碰撞的對(duì)象使用連續(xù)碰撞檢測(cè)
對(duì)靜態(tài)碰撞體(沒(méi)有剛體)使用連續(xù)碰撞檢測(cè)
對(duì)其他碰撞體使用離散碰撞檢測(cè)
用于快速移動(dòng)的對(duì)象
-
Continuous Speculative:連續(xù)推測(cè)檢測(cè)
對(duì)剛體和碰撞體使用推測(cè)性連續(xù)碰撞檢測(cè)
通常比連續(xù)碰撞檢測(cè)的成本更低
無(wú)剛體碰撞盒 Discrete Continuous Continuous Dynamic Continuous Speculative 無(wú)剛體碰撞盒 不檢測(cè)碰撞 Discrete Continuous Continuous Continuous Speculative Discrete Discrete Discrete Discrete Discrete Continuous Speculative Continuous Continuous Discrete Discrete Continuous Continuous Speculative Continuous Dynamic Continuous Discrete Continuous Continuous Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative 性能消耗關(guān)系:Continuous Dynamic > Continuous Speculative > Continuous > Discrete
-
-
Constrains:對(duì)剛體運(yùn)動(dòng)的約束
- Freeze Position:限制剛體在世界坐標(biāo)軸下 X、Y、Z 軸的移動(dòng)
- Freeze Rotation:限制剛體在世界坐標(biāo)軸下 X、Y、Z 軸的旋轉(zhuǎn)
-
Info:用于顯示參數(shù)的面板,不修改里面的值
二、碰撞器 Collider
? 碰撞器表示物體的體積(形狀)
? 碰撞器種類一共有 6 種:
- 盒狀碰撞器 Box Collider
- 球狀碰撞器 Sphere Collider
- 膠囊碰撞器 Capsule Collider
- 網(wǎng)格碰撞器 Mesh Collider
- 輪胎碰撞器 Wheel Collider
- 地形碰撞器 Terrain Collider
? 常用的為前 3 種
(一)共同參數(shù)
-
Edit Collider:編輯碰撞器的大小
-
Is Trigger:是否為觸發(fā)器
如果啟用,則該碰撞體用于觸發(fā)事件,并被物理引擎所忽略
主要用于進(jìn)行沒(méi)有物理效果的碰撞檢測(cè)
-
Material:物理材質(zhì)
可以確定碰撞體和其他對(duì)象碰撞時(shí)的交互(表現(xiàn))方式
-
Center:碰撞體的中心偏移位置
(二)常用碰撞器
- Box Collider
- Size:碰撞體在 X、Y、Z 方向上的大小
- Sphere Collider
- Radius:球形碰撞體的半徑大小
- Capsule Collider
- Radius:膠囊體的半徑
- Height:膠囊體的高度
- Direction:膠囊體在對(duì)象局部空間中的軸向
(三)異形物體使用多種碰撞器組合
? 剛體對(duì)象的子對(duì)象碰撞信息參與碰撞檢測(cè)
? 即父物體添加 Rigid Body,子物體設(shè)置 Collider。
(四)不常用碰撞器
-
Mesh Collider
-
Convex:是否為凸面的
勾選后,該 Mesh Collider 將會(huì)與其他 Mesh Collider 發(fā)生碰撞,最多支持 255 個(gè)三角面片
如果該對(duì)象添加了剛體 Rigid Body,則該選項(xiàng)必須勾選,否則會(huì)報(bào)錯(cuò)
-
Cooking Options:物理引擎對(duì)網(wǎng)格的處理方式
不常用
-
Mesh:引用需要用于碰撞的網(wǎng)格
-
-
Wheel Collider
賽車游戲中使用,其他時(shí)候不常用
注意:添加 Wheel Collider 后一定要添加 Rigid Body(或在父物體添加),否則將失效
-
Terrain Collider
地形系統(tǒng)中使用
性能較為低下,很少使用
三、物理材質(zhì)
? 在 Project 中創(chuàng)建物理材質(zhì) Physics Material


-
Dynamic Friction:滑動(dòng)摩擦力
0 表示絕對(duì)光滑,1 表示迅速靜止
-
Static Frction:靜摩擦力
0 表示絕對(duì)光滑,1 表示無(wú)法移動(dòng)
-
Bounciness:表面彈性
0 表示不會(huì)反彈,1 表示反彈沒(méi)有能量損失,甚至可能會(huì)增加少量能量
-
Friction Combine:摩擦力組合方式
- Average:取平均值
- Minimum:取最小值
- Maximum:取最大值
- Multiply:相乘
-
Bounce Combine:彈性組合方式
- Average:取平均值
- Minimum:取最小值
- Maximum:取最大值
- Multiply:相乘
四、碰撞檢測(cè)函數(shù)
? 碰撞和觸發(fā)響應(yīng)函數(shù)屬于特殊的生命周期函數(shù),也是通過(guò)反射調(diào)用
? 碰撞和觸發(fā)器函數(shù)都可以寫(xiě)成虛函數(shù),在子類去重寫(xiě)邏輯

(一)物理碰撞檢測(cè)響應(yīng)函數(shù)
// 碰撞觸發(fā)接觸時(shí)會(huì) 自動(dòng)執(zhí)行這個(gè)函數(shù)
private void OnCollisionEnter(Collision collision)
{
// Collision類型的 參數(shù) 包含了 碰到自己的對(duì)象的相關(guān)信息
// 關(guān)鍵參數(shù)
// 1.碰撞到的對(duì)象碰撞器的信息
collision.collider
// 2.碰撞對(duì)象的依附對(duì)象(GameObject)
collision.gameObject
// 3.碰撞對(duì)象的依附對(duì)象的位置信息
collision.transform
// 4.觸碰點(diǎn)數(shù)相關(guān)
collision.contactCount
// 接觸點(diǎn) 具體的坐標(biāo)
ContactPoint[] pos = collision.contacts;
// 只要得到了 碰撞到的對(duì)象的 任意一個(gè)信息 就可以得到它的所有信息
print(this.name + "被" + collision.gameObject.name + "撞到了");
}
// 碰撞結(jié)束分離時(shí) 會(huì)自動(dòng)執(zhí)行的函數(shù)
private void OnCollisionExit(Collision collision)
{
print(this.name + "被" + collision.gameObject.name + "結(jié)束碰撞了");
}
// 兩個(gè)物體相互接觸摩擦?xí)r 會(huì)不停的調(diào)用該函數(shù)
private void OnCollisionStay(Collision collision)
{
print(this.name + "一直在和" + collision.gameObject.name + "接觸");
}
(二)觸發(fā)器檢測(cè)響應(yīng)函數(shù)
// 觸發(fā)開(kāi)始的函數(shù) 當(dāng)?shù)谝淮谓佑|時(shí) 會(huì)自動(dòng)調(diào)用
protected virtual void OnTriggerEnter(Collider other)
{
print(this.name + "被" + other.gameObject.name + "觸發(fā)了");
}
// 觸發(fā)結(jié)束的函數(shù) 當(dāng)水乳相融的狀態(tài)結(jié)束時(shí) 會(huì)調(diào)用一次
private void OnTriggerExit(Collider other)
{
print(this.name + "被" + other.gameObject.name + "結(jié)束水乳相融的狀態(tài)了");
}
// 當(dāng)兩個(gè)對(duì)象 水乳相融的時(shí)候 會(huì)不停調(diào)用
private void OnTriggerStay(Collider other)
{
print(this.name + "和" + other.gameObject.name + "正在水乳相融");
}
-
只要掛載的對(duì)象能和別的物體產(chǎn)生碰撞或者觸發(fā),那么對(duì)應(yīng)的這 6 個(gè)函數(shù)就能夠被響應(yīng)
-
6 個(gè)函數(shù)不是說(shuō)都得寫(xiě),一般根據(jù)需求來(lái)進(jìn)行選擇書(shū)寫(xiě),一般用 Enter 函數(shù)較多
-
如果是一個(gè)異形物體,剛體在父對(duì)象上,如果你想通過(guò)子對(duì)象上掛腳本檢測(cè)碰撞是不行的,必須掛載到這個(gè)剛體父對(duì)象上才行
五、剛體加力
(一)剛體自帶添加力的方法
- 獲取剛體組件
rigidBody = this.GetComponent<Rigidbody>();
- 添加力
// 相對(duì)世界坐標(biāo)
// 世界坐標(biāo)系 Z軸正方向加了一個(gè)力
// 加力過(guò)后 對(duì)象是否停止移動(dòng) 是由阻力決定的
// 如果阻力為0 那給了一個(gè)力過(guò)后 始終 是不會(huì)停止運(yùn)動(dòng)
rigidBody.AddForce(Vector3.forward * 10);
// 如果想要在 世界坐標(biāo)系方法中 讓對(duì)象 相對(duì)于自己的面朝向動(dòng)
rigidBody.AddForce(this.transform.forward * 10);
// 相對(duì)本地坐標(biāo)
rigidBody.AddRelativeForce(Vector3.forward * 10);
//如果你希望即使有阻力 也希望對(duì)象一直動(dòng) 那你就把下面代碼放在Update函數(shù)中 一直“推”就行了
rigidBody.AddForce(Vector3.forward * 10);
- 添加扭矩力
// 相對(duì)世界坐標(biāo)
// 繞y軸旋轉(zhuǎn)
rigidBody.AddTorque(Vector3.up * 10);
// 相對(duì)本地坐標(biāo)
rigidBody.AddRelativeTorque(Vector3.up * 10);
- 直接改變速度
// 這個(gè)速度方向 是相對(duì)于 世界坐標(biāo)系的
// 如果要直接通過(guò)改變速度 來(lái)讓其移動(dòng) 一定要注意這一點(diǎn)
rigidBody.velocity = Vector3.forward * 5;
- 模擬爆炸效果
// 模擬爆炸的力 一定是 所有希望產(chǎn)生爆炸效果影響的對(duì)象
// 都需要得到他們的剛體 來(lái)執(zhí)行這個(gè)方法 才能都有效果
// 參數(shù)一 爆炸力
// 參數(shù)二 爆炸位置
// 參數(shù)三 爆炸半徑范圍
rigidBody.AddExplosionForce(100, Vector3.zero, 10);
(二)力的模式
// 第二個(gè)參數(shù) 力的模式 主要的作用 就是 計(jì)算方式不同而已
// 由于4中計(jì)算方式的不同 最終的移動(dòng)速度就會(huì)不同
rigidBody.AddForce(Vector3.forward * 10, ForceMode.Acceleration);
? 速度計(jì)算公式:v = F * t / m(動(dòng)量定理)
-
Acceleration
給物體增加一個(gè)持續(xù)的加速度,忽略其質(zhì)量
F = (0, 0, 10)、t = 0.02 s、m = 默認(rèn)為 1
v = 10 * 0.02 / 1 = 0.2 m/s
每物理幀移動(dòng) 0.2 m/s * 0.02 = 0.004 m -
Force
給物體添加一個(gè)持續(xù)的力,與物體的質(zhì)量有關(guān)
F = (0, 0, 10)、t = 0.02 s、m = 2 kg
v = 10 * 0.02 / 2 = 0.1 m/s
每物理幀移動(dòng) 0.1 m/s * 0.02 = 0.002 m -
Impulse
給物體添加一個(gè)瞬間的力,與物體的質(zhì)量有關(guān),忽略時(shí)間,t 默認(rèn)為1
F = (0, 0, 10)、t = 1 s、m = 2 kg
v = 10 * 1 / 2 = 5 m/s
每物理幀移動(dòng) 5 m/s * 0.02 = 0.1 m -
VelocityChange
給物體添加一個(gè)瞬時(shí)速度,忽略質(zhì)量,忽略時(shí)間
F = (0, 0, 10)、t = 1 s、m = 默認(rèn)為 1
v = 10 * 1 / 1 = 10 m/s
每物理幀移動(dòng) 10 m/s * 0.02 = 0.2 m
(三)力場(chǎng)
? 為物體添加 Constant Force,若物體之前沒(méi)有 Rigid Body,則會(huì)為其自動(dòng)添加

? 進(jìn)行參數(shù)設(shè)置

(四)剛體休眠
? Unity 為了節(jié)約性能,為剛體添加了休眠機(jī)制:
Rigidbody sleeping happens completely automatically. Whenever a rigidbody is slower than the sleepAngularVelocity and sleepVelocity it will start falling asleep. After a few frames of resting it will then be set to sleep. When the body is sleeping, no collision detection or simulation will be performed anymore. This saves a lot of CPU cycles.
剛體休眠完全自動(dòng)發(fā)生。只要?jiǎng)傮w的速度低于 sleepAngularVelocity 和 sleepVelocity,該剛體就會(huì)開(kāi)始休眠。其空閑一些幀后,就會(huì)被設(shè)置成休眠狀態(tài)。處于休眠狀態(tài)中的物體,不會(huì)再對(duì)其進(jìn)行碰撞檢測(cè)和模擬。這會(huì)節(jié)約大量的 CPU 開(kāi)銷。
? 例如,在為 Cube 添加 Rigid Body 后其下落靜止在平面上

? 將平面旋轉(zhuǎn)一定角度后,發(fā)現(xiàn) Cube 懸空,說(shuō)明此時(shí) Cube 的剛體休眠了

? 將平面向下以一定速度拖動(dòng),則 Cube 下落,剛體被激活文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-406487.html

? 使用代碼控制:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-406487.html
// 獲取剛體是否處于休眠狀態(tài) 如果是
if (rigidBody.IsSleeping())
{
// 就喚醒它
rigidBody.WakeUp();
}
到了這里,關(guān)于2022-04-20 Unity入門(mén)7——物理系統(tǒng)之碰撞檢測(cè)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!