Unity 布娃娃(Ragdoll)系统 让角色更加真实 (附实用Ragdoll插件详解)

布娃娃(Ragdoll)系统

布娃娃系统,相信很多玩家已经在大部分游戏中遇到过。作为一个已经成熟并且普及的系统,Ragdoll被广泛应用于各种游戏,来提供一定程度上的物理模拟。


9c251724-1825-11ec-ae30-e2cbc22591db~1.gif

图中是一个典型的Ragdoll应用场景,敌人在被一拳打飞后,在地面翻滚倒地,整个过程显得非常自然流畅。而且,在整个过程中,并没有用到任何传统“动画”,一切基于物理模拟效果。因而布娃娃系统,也是“程序生成动画”的一个重要手段。

模型与骨骼

模型

要理解Ragdoll系统为什么能实现物理模拟动画的效果,我们首先需要简单了解一下,传统3D游戏中动画的实现方式。(已经了解的同学可以直接跳到下一部分)

模型作为我们最常接触的美术资源,其本身是由一系列顶点(坐标)信息组成的数据集,因而显然,单纯的模型是纯静态的,我们在Unity->Gizoms中勾选Selection Wire就可以看到模型的线框图。 在Unity中可以看到Mesh Renderer系列组件,其中Mesh就是模型的网格。

image.png

那么让模型动起来,要做的就是让模型的各个顶点,按照一定规律运动起来,实现“动画”效果,这也是经典的“顶点动画”原理。

但是现代游戏,稍微复杂的一个模型常常有几千上万的顶点,让美术人员去手动设置每个顶点的运动情况显然不现实,也很难实现合理的效果。

于是人们想到现实中,人类靠骨骼带动肌肉运动,我们很少去直接控制身体上某块肌肉运动,更多是去驱动骨骼。只要骨骼按照一定规律运动,骨骼附带的肌肉也会随之运动,骨骼动画的概念应运而生。

骨骼

“骨骼”其实是一个抽象概念,它参考了人体利用骨骼带动肌肉运动的规律,为模型创建一个类似的、抽象的“骨骼”,如图所示。

image.png

图中就是一个包含骨骼的模型,这里利用了AnimationRigging插件中的BoneRenderer将骨骼以可视化的形式显示了出来(不然骨骼是一个抽象概念,并不对应某些可见实体)。可以看出,模型骨骼与人体骨骼非常相似,只是进行了一定程度上的简化。

那么实际上, Unity 中的骨骼,只是一系列具有父子层级关系的空物体,其层级结构一定程度上参考现实,父骨骼可以带动子骨骼运动(例如我们抬起大腿,小腿会跟随大腿运动),Unity的父子结构能够很好的表达这一特点。从父骨骼向子骨骼连线,就得到了上图中可视化的骨骼形状,更易于表现出骨骼的形态。

image.png

图中Armature表示的就是层级结构的骨骼,body则是人物模型,再次说明模型与骨骼是分离的。

蒙皮

所谓蒙皮,就是将模型的顶点附加到骨骼上的过程,也就是决定哪些“肌肉”受到哪些“骨骼”控制。建立好这样的绑定关系后,当我们驱动手臂“骨骼”时,手臂部分的顶点也会随之运动,从而将动画制作中的控制“顶点”运动简化为了控制“骨骼”运动。

而顶点的蒙皮信息中,包含了该顶点受到哪些骨骼影响(可以有多个),及每根骨骼的权重,这样在一些复杂运动的过程中,顶点跟随变化的轨迹会更加细腻真实,同时能消除关节连接处的一些撕裂情况。

image.png

Unity 中使用 Skinned Mesh Renderer(带蒙皮的网格渲染器)来实现这一效果。

骨骼动画

在拿到了一个蒙皮后的人物模型后,我们只需要控制骨骼运动便可以实现带动模型顶点运动。而动画数据,实际上就是记录了各个骨骼,在各个关键帧时的位置、旋转信息。同时利用一些算法实现关键帧间的插值,实现骨骼的平滑移动。(这部分一般交由动画师在专业软件中制作,俗称K动画,也就是K关键帧)

image.png

图中所示就是一个动画文件的信息,可以看到各个骨骼在每个关键帧的位置信息。 有了以上准备工作,我们的模型就可以动起来啦。

Ragdoll

搞清楚传统骨骼动画之后,Ragdoll的原理也就十分容易理解了。要想为人物添加Ragdoll效果,只需要在模型骨骼上挂载合适大小的碰撞体及刚体组件,让骨骼运动受物理模拟驱动(而非动画驱动),即可实现基于物理效果的布娃娃系统。

Unity 原生Ragdoll

Unity原生是提供Ragdoll功能的,我们可以右键模型Prefab -> 3D Object -> Ragdoll...

image.png

按提示把骨骼对应Transform拖入即可,注意的是,骨骼一般以髋关节为基础,大概在人物腰部偏下 配置好后,Unity会自动生成各肢体碰撞体,之后我们可以手动调整碰撞体形状以适应模型


image.png

这时我们再运行游戏,发现人物已经可以像布娃娃一样瘫倒了。

Unity原生的布娃娃系统功能非常简单,我们可以点进之前配置有碰撞体的骨骼节点观察一下。 可以看到肢体骨骼只是增加了一个RigidBody和Collider用于物理模拟,同时用CharacterJoint连接肢体模拟关节,剩余全部交给Unity物理系统进行模拟。

原生 Ragdoll 系统不足

看过Unity Ragdoll系统后,很明显能发现该套系统功能较为简单,有很大不足

  • 碰撞体、刚体等组件直接挂载在骨骼物体上,影响骨骼结构的简单性,增加了耦合度
  • 没有Animator组件,意味着该Ragdoll系统只能单纯受物理驱动,无法与动画融合(因此Unity官方也建议仅将该系统用于角色死亡时表现)
  • 状态切换很困难、难以扩展,且缺乏过渡(比如需要多套ragdoll不同表现时,要修改碰撞体和刚体参数同时控制启用)

Ragdoll Mecanim Mixer

Ragdoll Mecanim Mixer 插件正是为了解决上面的这些痛点而出现的,对于这些问题,该插件都实现了很好的解决方案(该插件可在Asset Store购买,目前Unity最好的Ragdoll插件之一)

  • Ragdoll碰撞体与骨骼分离,不直接关联,降低耦合度
  • 基于分离结构,可以分别计算物理变换与动画变换,并实现融合
  • 基于一套Ragdoll碰撞体可以预设多种状态,切换简单且可控制过渡平滑度

官方文档:https://assetstore.altinqiran.kz/ramecan-mixer/files/GUIDE_ENG.pdf

该插件主要由两个脚本组成

  • Ragdoll Constructor
  • Ramecan Mixer

Ragdoll Constructor

这个脚本主要用来为角色配置Ragdoll碰撞体及相关信息 挂载上脚本后,首先我们需要选择为哪些骨骼创建碰撞体,规则和Unity原生Ragdoll基本一致。 选好后我们可以手动创建一个Ragdoll Avatar(Scriptable Object),用来保存配置信息(选择已有配置可以避免每次重复设置)

image.png

之后我们就可以为每个骨骼设置碰撞体大小、质量、关节可活动范围等配置

[图片上传失败...(image-88e4e9-1661398137783)]

配置好Create后,我们就可以看到player外出现一个容器,其中Ragdoll作为单独的物体进行管理,与角色本身解耦

image.png

Ramecan Mixer

创建好Ragdoll后,我们可以看到player身上自动添加了一个RamecanMixer组件,这个组件主要负责控制多种状态切换及动画融合功能,可以配置每个骨骼的详细参数,可以参考官方文档,较容易理解

image.png
  • 当不需要Ragdoll物理效果时可以选择 Is Kinematic 和 Only Animation,完全交由动画驱动
  • 当需要Ragdoll物理效果时取消勾选 Is Kinematic,可以配置每根骨骼的详细参数和角度限制
  • 参数配置参考 (模拟尸体)见最后一节

配置好后,我们可以添加一个新的状态进行保存,之后可以用脚本控制切换 RamecanMixer.BeginStateTransition(Name)

RamecanMixer 原理分析

RamecanMixer 插件能够实现ragdoll与骨骼分离、实现动画融合等效果,其物理模拟依然是基于 Unity 物理引擎,主要在于其新增融合算法,并不难理解

在 Bone.cs 中我们可以看到对于Ragdoll骨骼的详细定义,其中两个参数可以留意一下

  • animTransform
  • physTransform

很明显,Ragdoll 骨骼分别记录了当前由动画驱动的骨骼 Transform(也就是模型骨骼),以及由物理驱动的 Ragdoll 骨骼Transform (位于Ragdoll物体下的一系列碰撞体)

在 RamecanMixer.cs 中,可以看到实现物理效果及与动画融合主要遵循以下流程

  • FixedUpdate() 中进行关于 RigidBody 的物理运算,主要是在 rigidbody 与动画骨骼出现偏差时,通过对 rigidbody 施力的方式去“弥补”差距,这样可以实现物体的“惯性”效果
  • Update() 中只进行简单的赋值操作,记录上一帧动画骨骼的变换信息
  • LateUpdate() 中进行的是核心的动画融合运算,同时会基于前一帧刚体变换与当前帧刚体变换进行插值,实现平滑过渡

有兴趣的可以仔细阅读插件源码,配有注释比较容易理解

Ragdoll 参数配置心得

上面介绍了 Ragdoll 实现原理,但是要想实现较好的模拟效果,需要对各个骨骼进行详细配置,同时反复耐心的调试,最终才能达到想要的效果,这里可以对一些重要参数提供一些参考,主要用于模拟的角色死亡效果

质量配比

要实现较好的布娃娃效果,最重要的是各骨骼的质量分配,这里建议以实际人体的质量分配为基准

  • 头部 – 7.30%
  • 躯干(胸部,背部和腹部) – 50.80%
  • 大腿 – 9.88%
  • 小腿 – 4.65%
  • 上臂 – 2.7%
  • 前臂 – 1.60%
  • 脚 – 1.45%
  • 手 – 0.66%

大腿等四肢,均指单条质量。人体总重设置60-100KG之间较为合理

image.png

即设置 Ragdoll 骨骼质量时不要严格遵循实际人体质量分布,要在实际质量的基础上乘以对应百分比,这个系数从髋部开始向上下逐渐递减 实际测试效果确实比严格遵循实际质量分布更为符合直觉

RamecanMixer参数

  • 开启self Collision
  • Rotation Accuracy设为0.2或更低(保证关节灵活度)
  • 角度限制开启(具体角度在Construct阶段已配置好,建议参考人体关节可动范围)
  • Joint Drive 中 Spring Rotation设为较低数值,保证关节可以摆动,数值较高会导致关节较硬(会努力回弹到原始形态)

总结

Unity 实现 Ragdoll 效果还是较为容易的,尤其是在现成插件的基础上,我们要做的主要工作就是详细配置 Ragdoll 参数,使其符合我们希望的效果。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容