简单实现一下,逻辑为:
在开启布娃娃之前,储存所有动作骨骼的相对位置和相对旋转度数。
关闭布娃娃时,先将骨骼相对位置和相对旋转度数,通过DoTween平滑恢复到之前的值,之后开启动画器。
using DG.Tweening;
using UnityEngine;
class rig_data//此类存储骨骼、相对位置、相对角度
{
public Transform rig;
public Vector3 Original_Pos;
public Vector3 Original_Rotate;
}
public class EnemyControl : MonoBehaviour
{
Animator ani;
List<rig_data> rig_Datas = new();
// Start is called before the first frame update
void Start()
{
ani = GetComponent<Animator>();
}
void Enable_RigDoll()//开启布娃娃
{
ani.enabled = false;
foreach (CharacterJoint joint in GetComponentsInChildren<CharacterJoint>())
{
joint.enableCollision = true;
joint.enablePreprocessing = true;
}
foreach (CapsuleCollider joint in GetComponentsInChildren<CapsuleCollider>())
{
joint.enabled = true;
}
foreach (BoxCollider joint in GetComponentsInChildren<BoxCollider>())
{
joint.enabled = true;
}
foreach (Rigidbody joint in GetComponentsInChildren<Rigidbody>())
{
joint.isKinematic = false;
rig_data data = new rig_data()//存储所有骨骼数据
{
rig = joint.transform,
Original_Pos = joint.transform.localPosition,
Original_Rotate = joint.transform.localEulerAngles,
};
rig_Datas.Add(data);
}
}
void Disable_RigDoll()#关闭布娃娃
{
foreach (CharacterJoint joint in GetComponentsInChildren<CharacterJoint>())
{
joint.enableCollision = false;
joint.enablePreprocessing = false;
}
foreach (CapsuleCollider joint in GetComponentsInChildren<CapsuleCollider>())
{
joint.enabled = false;
}
foreach (BoxCollider joint in GetComponentsInChildren<BoxCollider>())
{
joint.enabled = false;
}
foreach (Rigidbody joint in GetComponentsInChildren<Rigidbody>())
{
joint.isKinematic = true;
}
Back();
}
void Back()#骨骼恢复到原位置
{
for (int i = 0; i < rig_Datas.Count; i++)
{
rig_Datas[i].rig.DOLocalMove(rig_Datas[i].Original_Pos,2).SetEase(Ease.Linear);
rig_Datas[i].rig.DOLocalRotate(rig_Datas[i].Original_Rotate, 2).SetEase(Ease.Linear);
}
}
}