参考
https://docs.unity.cn/cn/2019.4/Manual/Joints.html
Unity物理关节全解析
关节组件将刚体连接到另一个刚体或空间中的固定点。关节施加使刚体移动的力,而关节限制功能可以限制该移动。
Unity 提供的以下关节可以对刚体组件施加不同的力和限制,从而使这些刚体具有不同的运动。
一、CharacterJoint角色关节
https://docs.unity.cn/cn/2019.4/Manual/class-CharacterJoint.html)
角色关节 (Character Joint) 主要用于布娃娃效果。此类关节是延长的球窝关节,可在每个轴上限制该关节,例如臀部或肩膀。沿所有线性自由度约束刚体移动,并实现所有角度自由度。连接到角色关节 (Character Joint) 的刚体围绕每个轴进行定向并从共享原点开始转动。
关于布娃娃和角色关节,本系列后续专门搞一篇来研究一下。
二、ConfigurableJoint可配置关节
https://docs.unity.cn/cn/2019.4/Manual/class-ConfigurableJoint.html
模拟任何骨骼关节,例如布娃娃中的关节。您可以配置此关节以任何自由度驱动和限制刚体的移动。
当您想要自定义布娃娃的运动并对角色强制实施某些姿势时,这种关节特别有用。使用可配置关节还可以将关节修改为您自行设计的高度专业化关节。
三、FixedJoint固定关节
https://docs.unity.cn/cn/2019.4/Manual/class-FixedJoint.html
限制刚体的移动以跟随所连接到的刚体的移动。当您需要一些可以轻松相互分离的刚体,或者您想连接两个刚体的移动而无需在 Transform 层级视图中进行父级化时,这种关节很有用。
固定关节 (Fixed Joint) 将对象的移动限制为依赖于另一个对象。这有点类似于管控 (Parenting),但是实现的方式是通过物理系统而不是变换 (Transform) 层级视图。使用固定关节的最佳场合是在希望对象可以轻松相互分离时,或者在没有管控情况下连接两个对象的移动。
在游戏中有时可能希望对象永久或暂时粘在一起。固定关节可能是比较适合用于这些情况的组件,因为不必通过脚本更改对象的层级视图来实现所需的效果。代价是所有使用固定关节的对象都必须使用刚体。
例如,如果要使用“粘性手榴弹”,可写一个脚本来检测与另一刚体(如敌人)的碰撞,然后创建一个固定关节并附加到该刚体。然后,当敌人四处移动时,关节将使手榴弹紧贴在他们身上。
四、HingeJoint铰链关节
https://docs.unity.cn/cn/2019.4/Manual/class-HingeJoint.html
在一个共享原点将一个刚体连接到另一个刚体或空间中的一个点,并允许刚体从该原点绕特定轴旋转。用于模拟门和手指关节。 也可用于模拟链条、钟摆等对象。
参考 Unity 关节
1.Hinge小车案例
在这个例子中,车头转向前进时,会带动车厢。
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;//最大转向角度
void Update()
{
float hor = Input.GetAxis("Horizontal");//左右偏离度
HeadRorate(hor);
float var = Input.GetAxis("Vertical");
HeadMove(var);
}
//车头轮子转向控制
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;
//和移动一样,每一帧都在旋转,不过最大旋转到Angla_Rorate
if (Mathf.Abs(AnglesNow + newAngles) >= Angla_Rorate)
newAngles = 0;
e.transform.Rotate(Vector3.right, newAngles, Space.Self);
}
}
//车头前进
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弹簧关节
https://docs.unity.cn/cn/2019.4/Manual/class-SpringJoint.html
使刚体彼此分开,但使刚体之间的距离略微拉伸。弹簧就像一块弹性物,试图将两个锚点一起拉到完全相同的位置。 拉力的强度与两个点之间的当前距离成比例,其中每单位距离的力由 Spring 属性设定。为了防止弹簧无休止振荡,可以设置 Damper 值,从而根据与两个对象之间的相对速度按比例减小弹簧力。值越高,振荡消失的速度越快。
1.发射小球案例
默认的小球是有弹簧关节的,发射出去后,取消关节,小球就会飞出去
void FireBall()
{
Destroy(obj_ball.GetComponent<SpringJoint>());
Destroy(obj_ball, 1);
}