參考
https://docs.unity.cn/cn/2019.4/Manual/Joints.html
Unity物理關(guān)節(jié)全解析
關(guān)節(jié)組件將剛體連接到另一個剛體或空間中的固定點(diǎn)。關(guān)節(jié)施加使剛體移動的力,而關(guān)節(jié)限制功能可以限制該移動。
Unity 提供的以下關(guān)節(jié)可以對剛體組件施加不同的力和限制,從而使這些剛體具有不同的運(yùn)動。
一、CharacterJoint角色關(guān)節(jié)
https://docs.unity.cn/cn/2019.4/Manual/class-CharacterJoint.html)
角色關(guān)節(jié) (Character Joint) 主要用于布娃娃效果。此類關(guān)節(jié)是延長的球窩關(guān)節(jié),可在每個軸上限制該關(guān)節(jié),例如臀部或肩膀。沿所有線性自由度約束剛體移動,并實(shí)現(xiàn)所有角度自由度。連接到角色關(guān)節(jié) (Character Joint) 的剛體圍繞每個軸進(jìn)行定向并從共享原點(diǎn)開始轉(zhuǎn)動。
關(guān)于布娃娃和角色關(guān)節(jié),本系列后續(xù)專門搞一篇來研究一下。
二、ConfigurableJoint可配置關(guān)節(jié)
https://docs.unity.cn/cn/2019.4/Manual/class-ConfigurableJoint.html
模擬任何骨骼關(guān)節(jié),例如布娃娃中的關(guān)節(jié)。您可以配置此關(guān)節(jié)以任何自由度驅(qū)動和限制剛體的移動。
當(dāng)您想要自定義布娃娃的運(yùn)動并對角色強(qiáng)制實(shí)施某些姿勢時,這種關(guān)節(jié)特別有用。使用可配置關(guān)節(jié)還可以將關(guān)節(jié)修改為您自行設(shè)計的高度專業(yè)化關(guān)節(jié)。
三、FixedJoint固定關(guān)節(jié)
https://docs.unity.cn/cn/2019.4/Manual/class-FixedJoint.html
限制剛體的移動以跟隨所連接到的剛體的移動。當(dāng)您需要一些可以輕松相互分離的剛體,或者您想連接兩個剛體的移動而無需在 Transform 層級視圖中進(jìn)行父級化時,這種關(guān)節(jié)很有用。
固定關(guān)節(jié) (Fixed Joint) 將對象的移動限制為依賴于另一個對象。這有點(diǎn)類似于管控 (Parenting),但是實(shí)現(xiàn)的方式是通過物理系統(tǒng)而不是變換 (Transform) 層級視圖。使用固定關(guān)節(jié)的最佳場合是在希望對象可以輕松相互分離時,或者在沒有管控情況下連接兩個對象的移動。
在游戲中有時可能希望對象永久或暫時粘在一起。固定關(guān)節(jié)可能是比較適合用于這些情況的組件,因?yàn)椴槐赝ㄟ^腳本更改對象的層級視圖來實(shí)現(xiàn)所需的效果。代價是所有使用固定關(guān)節(jié)的對象都必須使用剛體。
例如,如果要使用“粘性手榴彈”,可寫一個腳本來檢測與另一剛體(如敵人)的碰撞,然后創(chuàng)建一個固定關(guān)節(jié)并附加到該剛體。然后,當(dāng)敵人四處移動時,關(guān)節(jié)將使手榴彈緊貼在他們身上。
四、HingeJoint鉸鏈關(guān)節(jié)
https://docs.unity.cn/cn/2019.4/Manual/class-HingeJoint.html
在一個共享原點(diǎn)將一個剛體連接到另一個剛體或空間中的一個點(diǎn),并允許剛體從該原點(diǎn)繞特定軸旋轉(zhuǎn)。用于模擬門和手指關(guān)節(jié)。 也可用于模擬鏈條、鐘擺等對象。
1.Hinge小車案例
在這個例子中,車頭轉(zhuǎn)向前進(jìn)時,會帶動車廂。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//主要控制車頭,然后車頭通過鉸鏈和車廂連接
public class DriveControl : MonoBehaviour
{
public GameObject[] obj_lunzi;
public GameObject Car_Head;
public float Speed_Rorate = 10f;
public float Angla_Rorate = 60f;
public float Speed_Move = 10f;
public float AnglesNow = 0f;//最大轉(zhuǎn)向角度
void Update()
{
float hor = Input.GetAxis("Horizontal");//左右偏離度
HeadRorate(hor);
float var = Input.GetAxis("Vertical");
HeadMove(var);
}
//車頭輪子轉(zhuǎn)向控制
void HeadRorate(float hor)
{
if (Mathf.Abs(hor - 0.0f) <= 0.1f)
return;
foreach (GameObject e in obj_lunzi)
{
if (e.transform.localEulerAngles.y <= 180)
AnglesNow = e.transform.localEulerAngles.y;
else if (e.transform.localEulerAngles.y > 180)
AnglesNow = e.transform.localEulerAngles.y - 360;
float newAngles = Time.deltaTime * hor * Speed_Rorate;
//和移動一樣,每一幀都在旋轉(zhuǎn),不過最大旋轉(zhuǎn)到Angla_Rorate
if (Mathf.Abs(AnglesNow + newAngles) >= Angla_Rorate)
newAngles = 0;
e.transform.Rotate(Vector3.right, newAngles, Space.Self);
}
}
//車頭前進(jìn)
void HeadMove(float var)
{
float PI = 3.1415926f;
float A = AnglesNow * PI / 180;
Vector3 Dir = new Vector3(Mathf.Sin(A), 0, Mathf.Cos(A));
float Speed = Time.deltaTime * var * Speed_Move;
Car_Head.transform.Translate(Dir.normalized * Speed, Space.Self);
}
}
五、SpringJoint彈簧關(guān)節(jié)
https://docs.unity.cn/cn/2019.4/Manual/class-SpringJoint.html
使剛體彼此分開,但使剛體之間的距離略微拉伸。彈簧就像一塊彈性物,試圖將兩個錨點(diǎn)一起拉到完全相同的位置。 拉力的強(qiáng)度與兩個點(diǎn)之間的當(dāng)前距離成比例,其中每單位距離的力由 Spring 屬性設(shè)定。為了防止彈簧無休止振蕩,可以設(shè)置 Damper 值,從而根據(jù)與兩個對象之間的相對速度按比例減小彈簧力。值越高,振蕩消失的速度越快。
1.發(fā)射小球案例
默認(rèn)的小球是有彈簧關(guān)節(jié)的,發(fā)射出去后,取消關(guān)節(jié),小球就會飛出去
void FireBall()
{
Destroy(obj_ball.GetComponent<SpringJoint>());
Destroy(obj_ball, 1);
}