效果展示
正如其名,Ragdoll可以讓人物模型實現像布娃娃一樣物理效果
創建Ragdoll
在場景中新建 3D Object → Ragdoll...
接下來是一個初見復雜的綁定界面,這里我做了簡單翻譯
我們需要將模型對應的關節部位一一拉進這個表
創建完成后,可以發現模型中的每個所選部位中多了一個Rigibody,一個Collider和一個Character Joint組件,在Joint面板里可以調節轉動限制等
這里要注意的一個坑點是,root節點是沒有Character Joint的,當你找不到root節點時,沒有Character Joint但是添加了Box Collider和Rigibody的就是root節點
root節點應在這個位置,不熟悉朋友有可能將盆骨附近Pelvis 與 胸部附近Middle Spine的兩個Collider互換位置,或者重疊,這將導致整個人物的抽搐,蒙皮拉伸
調整四肢Collider大小位置,如下:
通過代碼控制
如果我需要的效果是:
- 讓角色存活(isDead = false)時:每個部位的Rigibody的isKinematic一直為true,每個部位的Collider的isTrigger也為true
- 角色死亡(isDead = true)時:每個部位的Rigibody的isKinematic變為false,每個部位的Collider的isTrigger也變為false,同時,必須將角色的Animation組件去除
代碼
我的做法是使用GetComponentsInChildren函數獲得所有剛體,再通過每個剛體獲取這個部位上的Collider,用兩個List將他們存儲起來。就可以方便的設置isKinematic和isTrigger
同時在死亡的下一幀用協程關閉動畫組件,(如果想讓角色復活,Anmiaton組件的enable屬性設置為true即可)
完整代碼如下:
public List<Rigidbody> ragdollRigidbodys = new List<Rigidbody>();
public List<Collider> ragdollColliders = new List<Collider>();
void InitRagdoll() {
Rigidbody[] _rigidbodys = GetComponentsInChildren<Rigidbody>();
for (int i = 0; i < _rigidbodys.Length; i++) {
if (_rigidbodys[i] == rigidbody)
continue;
ragdollRigidbodys.Add(_rigidbodys[i]);
_rigidbodys[i].isKinematic = true;
Collider _collider = _rigidbodys[i].gameObject.GetComponent<Collider>();
_collider.isTrigger = true;
ragdollColliders.Add(_collider);
}
}
void EnableRagdoll() {
for (int i = 0; i < ragdollRigidbodys.Count; i++) {
ragdollRigidbodys[i].isKinematic = false;
ragdollColliders[i].isTrigger = false;
}
Collider collidercontroller = rigidbody.gameObject.GetComponent<Collider>();
collidercontroller.enabled = false;
rigidbody.isKinematic = true;
StartCoroutine(CloseAnimator());
}
IEnumerator CloseAnimator() {
yield return new WaitForEndOfFrame();
animator.enabled = false;
this.enabled = false;
}
最終效果就是這樣了,死亡之后的布娃娃狀態真的很有意思
坑點總結
第一幀蒙皮拉伸,撕裂
Play之后的第一幀(先點暫停再Play可查看第一幀)可能出現角色關節撕裂,Play之后角色亂動
解決方案:
-
檢查pelvis和middle spine是否混淆,root節點設置錯誤(root節點是有剛體,有碰撞器沒有Character Joint)
-
檢查兩個部位的collider是否產生重疊
死亡后蒙皮拉伸,撕裂
解決方案:
可以嘗試勾選Character Joint組建的Enable Projection選項
死亡后布娃娃不生效
解決方案:
檢查是否有關Animator組件