參考
一文搞懂 Unity 布娃娃(Ragdoll)系統(tǒng) 讓角色更加真實(shí) (附實(shí)用Ragdoll插件詳解)
如何用Unity做出真實(shí)的布娃娃互動(dòng)效果?
Unity3D RagDoll(布娃娃系統(tǒng))詳解
一、布娃娃向?qū)?/h5>
官方文檔https://docs.unity.cn/cn/2019.4/Manual/wizard-RagdollWizard.html寫(xiě)的太簡(jiǎn)略了,可以參考B站的視頻如何使用Unity的布娃娃系統(tǒng)【Ragdoll】,這里我自己做了一遍,簡(jiǎn)單總結(jié)一下:
1.把模型拖到場(chǎng)景里,打開(kāi)布娃娃向?qū)?,進(jìn)行綁定,然后保存為預(yù)制體
我用了別的模型發(fā)現(xiàn)骨骼不太對(duì),還是從商店里下載視頻作者使用的免費(fèi)資源“BodyGuards”

導(dǎo)入后,把模型SkelMesh_Bodyguard_01拖入場(chǎng)景。然后從菜單欄中選擇 GameObject > 3D Object > Ragdoll… 以打開(kāi)布娃娃向?qū)?,按照部分綁定,記得最后改一下重量?/p>

現(xiàn)在選中模型,能看到添加的剛體輪廓。選 中節(jié)點(diǎn),能看到添加的組件:

角色關(guān)節(jié),可參考https://docs.unity.cn/cn/2019.4/Manual/class-CharacterJoint.html
2.需要打開(kāi)Physics Debugger協(xié)助微調(diào)


可以看到腿部紅色的碰撞體太粗了,手臂生成的碰撞體也不對(duì),要一點(diǎn)點(diǎn)調(diào)整。

這是調(diào)整后的結(jié)果,模型撞到下方的斜方塊后,會(huì)有布娃娃效果,不過(guò)手部僵硬,關(guān)節(jié)的彎曲角度也不正常。
3.給手添加碰撞

這里視頻UP主總是添加不上Connected Body,是因?yàn)橐付ǜ腹?jié)點(diǎn),而不是自身。
4.修改關(guān)節(jié)的彎曲角度

但是這里我設(shè)置的效果很不好,看了https://docs.unity.cn/cn/2019.4/Manual/class-CharacterJoint.html也沒(méi)搞明白那幾個(gè)軸。
5.Animator和布娃娃無(wú)法同時(shí)存在
默認(rèn)是播放動(dòng)畫(huà)狀態(tài):此時(shí)所有帶RigidBody節(jié)點(diǎn)的Is Kinematic勾選,Animator組件啟用。
當(dāng)需要啟動(dòng)布娃娃時(shí),使用代碼將所有帶RigidBody節(jié)點(diǎn)的Is Kinematic取消勾選,Animator組件禁用。
在unity 布娃娃系統(tǒng)的開(kāi)啟關(guān)閉提供了代碼參考:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RangdollController : MonoBehaviour {
private Animator Anim;
// Use this for initialization
void Start () {
Anim = GetComponent<Animator>();
InitRagdoll();
}
// Update is called once per frame
void Update () {
}
public List<Rigidbody> RagdollRigidbodys = new List<Rigidbody>();
public List<Collider> RagdollColliders = new List<Collider>();
/// <summary>
/// 初始化,遍歷角色身體上的所有ragdoll并存儲(chǔ) 此時(shí)關(guān)閉布娃娃系統(tǒng)
/// </summary>
void InitRagdoll()
{
Rigidbody[] Rigidbodys = GetComponentsInChildren<Rigidbody>();
for (int i = 0; i < Rigidbodys.Length; i++)
{
if (Rigidbodys[i] == GetComponent<Rigidbody>())
{
//排除正常狀態(tài)的Rigidbody
continue;
}
//添加Rigidbody和Collider到List
RagdollRigidbodys.Add(Rigidbodys[i]);
Rigidbodys[i].isKinematic = true;
Collider RagdollCollider = Rigidbodys[i].gameObject.GetComponent<Collider>();
RagdollCollider.isTrigger = true;
RagdollColliders.Add(RagdollCollider);
}
}
/// <summary>
/// 啟動(dòng)布娃娃系統(tǒng)
/// </summary>
public void EnableRagdoll()
{
//開(kāi)啟布娃娃狀態(tài)的所有Rigidbody和Collider
for (int i = 0; i < RagdollRigidbodys.Count; i++)
{
RagdollRigidbodys[i].isKinematic = false;
RagdollColliders[i].isTrigger = false;
}
//關(guān)閉正常狀態(tài)的Collider
GetComponent<Collider>().enabled = false;
//下一幀關(guān)閉正常狀態(tài)的動(dòng)畫(huà)系統(tǒng)
StartCoroutine(SetAnimatorEnable(false));
}
/// <summary>
/// 關(guān)閉布娃娃系統(tǒng)
/// </summary>
public void DisableRagdoll()
{
//關(guān)閉布娃娃狀態(tài)的所有Rigidbody和Collider
for (int i = 0; i < RagdollRigidbodys.Count; i++)
{
RagdollRigidbodys[i].isKinematic = true;
RagdollColliders[i].isTrigger = true;
}
//開(kāi)啟正常狀態(tài)的Collider
GetComponent<Collider>().enabled = true;
//下一幀開(kāi)啟正常狀態(tài)的動(dòng)畫(huà)系統(tǒng)
StartCoroutine(SetAnimatorEnable(true));
}
IEnumerator SetAnimatorEnable(bool Enable)
{
yield return new WaitForEndOfFrame();
Anim.enabled = Enable;
}
6.坑
- 播放布娃娃的時(shí)候要把a(bǔ)nimator勾掉,不然不生效
- 部位穿插拉伸,要把部位Character Joint組件上面的Enable Projection勾上
- 激活布娃娃彈得很高,就是剛體的速度,把rigidbody的速度置為0
- 如果布娃娃動(dòng)作僵硬,肯定用錯(cuò)骨骼來(lái)綁定布娃娃導(dǎo)致的
- 布娃娃穿透場(chǎng)景碰撞的問(wèn)題,其實(shí)這個(gè)由于速度太快引起的,可以設(shè)置rigidbody的碰撞檢測(cè)模式collisionDetectionMode
- 受力不要全部部位都給力,一般都是給一個(gè)部位就夠了,不然各種力作用引起怪異表現(xiàn)
- 關(guān)于倒地之后抖動(dòng)問(wèn)題,這個(gè)只能加個(gè)檢測(cè),如果所有剛體速度小于某個(gè)數(shù)則關(guān)閉剛體功能
7.官方文檔 關(guān)節(jié)和布娃娃穩(wěn)定性
https://docs.unity.cn/cn/2019.4/Manual/RagdollStability.html
二、插件Ragdoll Mecanim Mixer
1.Ragdoll 原理
跟著布娃娃向?qū)ё鐾曛?,原理也就十分容易理解了。要想為人物添加Ragdoll效果,只需要在模型骨骼上掛載合適大小的碰撞體及剛體組件,讓骨骼運(yùn)動(dòng)受物理模擬驅(qū)動(dòng)(而非動(dòng)畫(huà)驅(qū)動(dòng)),即可實(shí)現(xiàn)基于物理效果的布娃娃系統(tǒng)。
Unity原生的布娃娃系統(tǒng)功能非常簡(jiǎn)單,我們可以點(diǎn)進(jìn)之前配置有碰撞體的骨骼節(jié)點(diǎn)觀察一下。 可以看到肢體骨骼只是增加了一個(gè)RigidBody和Collider用于物理模擬,同時(shí)用CharacterJoint連接肢體模擬關(guān)節(jié),剩余全部交給Unity物理系統(tǒng)進(jìn)行模擬。
2.原生 Ragdoll 系統(tǒng)不足
看過(guò)Unity Ragdoll系統(tǒng)后,很明顯能發(fā)現(xiàn)該套系統(tǒng)功能較為簡(jiǎn)單,有很大不足
- 碰撞體、剛體等組件直接掛載在骨骼物體上,影響骨骼結(jié)構(gòu)的簡(jiǎn)單性,增加了耦合度
- 沒(méi)有Animator組件,意味著該Ragdoll系統(tǒng)只能單純受物理驅(qū)動(dòng),無(wú)法與動(dòng)畫(huà)融合(因此Unity官方也建議僅將該系統(tǒng)用于角色死亡時(shí)表現(xiàn))
- 狀態(tài)切換很困難、難以擴(kuò)展,且缺乏過(guò)渡(比如需要多套ragdoll不同表現(xiàn)時(shí),要修改碰撞體和剛體參數(shù)同時(shí)控制啟用)
3.插件Ragdoll Mecanim Mixer
Ragdoll Mecanim Mixer 插件正是為了解決上面的這些痛點(diǎn)而出現(xiàn)的,對(duì)于這些問(wèn)題,該插件都實(shí)現(xiàn)了很好的解決方案(該插件可在Asset Store購(gòu)買(mǎi),目前Unity最好的Ragdoll插件之一)
- Ragdoll碰撞體與骨骼分離,不直接關(guān)聯(lián),降低耦合度
- 基于分離結(jié)構(gòu),可以分別計(jì)算物理變換與動(dòng)畫(huà)變換,并實(shí)現(xiàn)融合
- 基于一套R(shí)agdoll碰撞體可以預(yù)設(shè)多種狀態(tài),切換簡(jiǎn)單且可控制過(guò)渡平滑度
官方文檔:https://assetstore.altinqiran.kz/ramecan-mixer/files/GUIDE_ENG.pdf
該插件主要由兩個(gè)腳本組成
- Ragdoll Constructor
- Ramecan Mixer