网易大咖分享之从Unity_RagDoll系统科普到动画全部基础原理
关注我博客的同学应该知道,这个星期都在做一些MMD动作相关的,刚好做到动作这快
十分惭愧!工作多年,还没好好系统地分析过动作这块
今天带来网易大咖(可能只是工作室内的小小员工,网易还有分大的产品组,下面才是各小小工作室,然后其中里面的一个员工,可以吊打市面80%游戏从业人员)的分享
(当然,以下内容和公司真正工作内容还是有些出入,各公司之间人员,做法等也会有很大差别,不能盲目相信或者模仿某一种做法,这里仅仅是转载一些基础知识,请按自身需要挑选食用)
关键还是大量的相关知识阅读,“内化”,举一反三,能快速解决自身当前的问题
一文搞懂 Unity 布娃娃(Ragdoll)系统 让角色更加真实 (附实用Ragdoll插件详解)
布娃娃(Ragdoll)系统
布娃娃系统,相信很多玩家已经在大部分游戏中遇到过。作为一个已经成熟并且普及的系统,Ragdoll被广泛应用于各种游戏,来提供一定程度上的物理模拟。
图中是一个典型的Ragdoll应用场景,敌人在被一拳打飞后,在地面翻滚倒地,整个过程显得非常自然流畅。而且,在整个过程中,并没有用到任何传统“动画”,一切基于物理模拟效果。因而布娃娃系统,也是“程序生成动画”的一个重要手段。
模型与骨骼
模型
要理解Ragdoll系统为什么能实现物理模拟动画的效果,我们首先需要简单了解一下,传统3D游戏中动画的实现方式。(已经了解的同学可以直接跳到下一部分)
模型作为我们最常接触的美术资源,其本身是由一系列顶点(坐标)信息组成的数据集,因而显然,单纯的模型是纯静态的,我们在Unity->Gizoms中勾选Selection Wire就可以看到模型的线框图。 在Unity中可以看到Mesh Renderer系列组件,其中Mesh就是模型的网格。
那么让模型动起来,要做的就是让模型的各个顶点,按照一定规律运动起来,实现“动画”效果,这也是经典的“顶点动画”原理。
但是现代游戏,稍微复杂的一个模型常常有几千上万的顶点,让美术人员去手动设置每个顶点的运动情况显然不现实,也很难实现合理的效果。
于是人们想到现实中,人类靠骨骼带动肌肉运动,我们很少去直接控制身体上某块肌肉运动,更多是去驱动骨骼。只要骨骼按照一定规律运动,骨骼附带的肌肉也会随之运动,骨骼动画的概念应运而生。
骨骼
“骨骼”其实是一个抽象概念,它参考了人体利用骨骼带动肌肉运动的规律,为模型创建一个类似的、抽象的“骨骼”,如图所示。
图中就是一个包含骨骼的模型,这里利用了AnimationRigging插件中的BoneRenderer将骨骼以可视化的形式显示了出来(不然骨骼是一个抽象概念,并不对应某些可见实体)。可以看出,模型骨骼与人体骨骼非常相似,只是进行了一定程度上的简化。
那么实际上, Unity 中的骨骼,只是一系列具有父子层级关系的空物体,其层级结构一定程度上参考现实,父骨骼可以带动子骨骼运动(例如我们抬起大腿,小腿会跟随大腿运动),Unity的父子结构能够很好的表达这一特点。从父骨骼向子骨骼连线,就得到了上图中可视化的骨骼形状,更易于表现出骨骼的形态。
图中Armature表示的就是层级结构的骨骼,body则是人物模型,再次说明模型与骨骼是分离的。
蒙皮
所谓蒙皮,就是将模型的顶点附加到骨骼上的过程,也就是决定哪些“肌肉”受到哪些“骨骼”控制。建立好这样的绑定关系后,当我们驱动手臂“骨骼”时,手臂部分的顶点也会随之运动,从而将动画制作中的控制“顶点”运动简化为了控制“骨骼”运动。
而顶点的蒙皮信息中,包含了该顶点受到哪些骨骼影响(可以有多个),及每根骨骼的权重,这样在一些复杂运动的过程中,顶点跟随变化的轨迹会更加细腻真实,同时能消除关节连接处的一些撕裂情况。
Unity 中使用 Skinned Mesh Renderer(带蒙皮的网格渲染器)来实现这一效果。
骨骼动画
在拿到了一个蒙皮后的人物模型后,我们只需要控制骨骼运动便可以实现带动模型顶点运动。而动画数据,实际上就是记录了各个骨骼,在各个关键帧时的位置、旋转信息。同时利用一些算法实现关键帧间的插值,实现骨骼的平滑移动。(这部分一般交由动画师在专业软件中制作,俗称K动画,也就是K关键帧)
图中所示就是一个动画文件的信息,可以看到各个骨骼在每个关键帧的位置信息。 有了以上准备工作,我们的模型就可以动起来啦。
Ragdoll
搞清楚传统骨骼动画之后,Ragdoll的原理也就十分容易理解了。要想为人物添加Ragdoll效果,只需要在模型骨骼上挂载合适大小的碰撞体及刚体组件,让骨骼运动受物理模拟驱动(而非动画驱动),即可实现基于物理效果的布娃娃系统。
Unity 原生Ragdoll
Unity原生是提供Ragdoll功能的,我们可以右键模型Prefab -> 3D Object -> Ragdoll...
按提示把骨骼对应Transform拖入即可,注意的是,骨骼一般以髋关节为基础,大概在人物腰部偏下 配置好后,Unity会自动生成各肢体碰撞体,之后我们可以手动调整碰撞体形状以适应模型
这时我们再运行游戏,发现人物已经可以像布娃娃一样瘫倒了。
Unity原生的布娃娃系统功能非常简单,我们可以点进之前配置有碰撞体的骨骼节点观察一下。 可以看到肢体骨骼只是增加了一个RigidBody和Collider用于物理模拟,同时用CharacterJoint连接肢体模拟关节,剩余全部交给Unity物理系统进行模拟。
原生 Ragdoll 系统不足
看过Unity Ragdoll系统后,很明显能发现该套系统功能较为简单,有很大不足
- 碰撞体、刚体等组件直接挂载在骨骼物体上,影响骨骼结构的简单性,增加了耦合度
- 没有Animator组件,意味着该Ragdoll系统只能单纯受物理驱动,无法与动画融合(因此Unity官方也建议仅将该系统用于角色死亡时表现)
- 状态切换很困难、难以扩展,且缺乏过渡(比如需要多套ragdoll不同表现时,要修改碰撞体和刚体参数同时控制启用)
Ragdoll Mecanim Mixer
Ragdoll Mecanim Mixer 插件正是为了解决上面的这些痛点而出现的,对于这些问题,该插件都实现了很好的解决方案(该插件可在Asset Store购买,目前Unity最好的Ragdoll插件之一)
- Ragdoll碰撞体与骨骼分离,不直接关联,降低耦合度
- 基于分离结构,可以分别计算物理变换与动画变换,并实现融合
- 基于一套Ragdoll碰撞体可以预设多种状态,切换简单且可控制过渡平滑度
官方文档:assetstore.altinqiran.kz/ramecan-mix…
该插件主要由两个脚本组成
- Ragdoll Constructor
- Ramecan Mixer
Ragdoll Constructor
这个脚本主要用来为角色配置Ragdoll碰撞体及相关信息 挂载上脚本后,首先我们需要选择为哪些骨骼创建碰撞体,规则和Unity原生Ragdoll基本一致。 选好后我们可以手动创建一个Ragdoll Avatar(Scriptable Object),用来保存配置信息(选择已有配置可以避免每次重复设置)
之后我们就可以为每个骨骼设置碰撞体大小、质量、关节可活动范围等配置
配置好Create后,我们就可以看到player外出现一个容器,其中Ragdoll作为单独的物体进行管理,与角色本身解耦
Ramecan Mixer
创建好Ragdoll后,我们可以看到player身上自动添加了一个RamecanMixer组件,这个组件主要负责控制多种状态切换及动画融合功能,可以配置每个骨骼的详细参数,可以参考官方文档,较容易理解
- 当不需要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之间较为合理
在研究了顽皮狗在 GDC2017 上关于 Ragdoll 的演讲(Physics Animation in Uncharted 4: A Thief's End)后,发现他们对于质量分布有一套经验规律
即设置 Ragdoll 骨骼质量时不要严格遵循实际人体质量分布,要在实际质量的基础上乘以对应百分比,这个系数从髋部开始向上下逐渐递减 实际测试效果确实比严格遵循实际质量分布更为符合直觉
RamecanMixer参数
- 开启self Collision
- Rotation Accuracy设为0.2或更低(保证关节灵活度)
- 角度限制开启(具体角度在Construct阶段已配置好,建议参考人体关节可动范围)
- Joint Drive 中 Spring Rotation设为较低数值,保证关节可以摆动,数值较高会导致关节较硬(会努力回弹到原始形态)
总结
Unity 实现 Ragdoll 效果还是较为容易的,尤其是在现成插件的基础上,我们要做的主要工作就是详细配置 Ragdoll 参数,使其符合我们希望的效果。 之后我会基于这套系统研究一下除死亡动画外,Ragdoll与其他动作的物理融合(如攀爬等),希望实现顽皮狗在神海4中的物理效果
顽皮狗GDC参考链接:www.youtube.com/watch?v=7S-…
网易大咖分享之从Unity_RagDoll系统科普到动画全部基础原理相关推荐
- 大咖分享会 | 百度首次揭秘如何构建用户画像与移动统计
从11年开始,互联网进入大数据时代,相比传统的调查分析,大数据是企业通过互联网便利的获取用户更广泛的反馈信息,为进一步精准.快速地分析用户行为习惯.消费习惯等重要商业信息,提供了足够的数据基础.本次P ...
- 【PMCAFF大咖分享会】揭秘大数据驱动下的京东供应链体系
报名方式:回复"报名线下"至公众号,即可进入报名环节 时间:10月24日(周六)14:00-18:00 地点:待定(录取后统一发送邮件通知地址) 费用:免费 讲师简介 ▍翟松涛个人 ...
- 快讯 | 公链专场,四位大咖分享了些什么(附PPT)
8月11日,由CSDN主办,区块链大本营.柏链道捷.极客帮创投.孔壹学院.ChainDesk.壹金链数字加密谷.准脉90孵化器协办的第十期区块链技术沙龙,在北京中关村软件园如期举办. 本期区块链 ...
- 腾讯云大学大咖分享 | 深入浅出话智能语音识别
语音识别就是把语音变成文字的过程,相信大家在平时生活也已经用到过一些语音识别的场景,比如说语音输入法.地图产品的语音输入.近年来,随着互联网的发展,各种音频数据和文本数据得到不断积累和丰富,CPU.G ...
- 腾讯云大学大咖分享 | 物联网边缘计算的前生今世与实践
点击观看完整课程 2019年在网络科技领域最火热技术名称是什么?物联网.5G.边缘计算想必这些词汇大家早已是耳熟能详,听了这么久的热词,相信各位也会有很多的疑问.为什么边缘计算会突然热起来?为什么云计 ...
- 腾讯云大学大咖分享 | 探索云直播技术
点击观看完整课程 直播行业规模逐年增加,但行业增速却在逐步放缓,视频直播的平台对于各大厂商的解决方案提出了更多.更个性化的要求.是什么样的技术和服务在背后支撑着我们日常直播内容发布和播放呢?今天我们通 ...
- 公司技术大咖分享会--后记
公司技术大咖分享会--后记 今天下午公司内部召开了个后台开发人员技术分享会,总共7个人,兵不在多:三个华为资深大咖给我们分享了程序员那些事,凭我仅有的记忆现在把它记下,希望对之后的职业生涯有所帮助. ...
- 三包围结构的字是什么样的_手帐排版的高段位秘诀:运用艺术字丨大咖分享
这是手帐进化论的第212篇文章编辑 / 饭团儿君 之前在建立手帐群时,我的建群初衷之一,就是希望提供一个平台,给大家互相交流手帐.互相提高技巧的机会,同时,希望手帐群可以作为一个沙龙基地,帮大家邀请手 ...
- PMcaff脉脉大咖分享会 | 走出BAT!从0到1做一款自己的产品
由PMcaff和脉脉联合主办的大咖分享会第二期,邀请了友友租车产品负责人江宽和慕课网产品负责人张国政.两位嘉宾都曾任职于国内知名互联网公司,他们在离开大公司的体系和资源优势后,从零开始,重新打造一款自 ...
最新文章
- R语言嵌套方差分析(Nested ANOVA)实战
- 如何简单地理解Python中的if __name__ == '__main__'
- Q1全球智能机销量增长3.9% 三星苹果华为居三甲
- MySQL索引背后的数据结构及算法原理zz
- Laravel Conf China 2019 之 安正超
- MsWord 操作总结
- YOLOv4改进版重磅问世!Yolov4扩展版!Yolov4原班人马重磅推出Scaled-YOLOv4: Scaling Cross Stage Partial Network
- HDU4612+Tarjan缩点+BFS求树的直径
- Python函数调用(2)
- 创业负债累累 | 失败了的我还如何翻盘?是天台见! 我的故事还只是从这件事开始...
- linux之ext、ext1、ext2、ext3、ext4文件系统的区别及常用命令
- 云计算对21世纪IT人的挑战
- 读取图像数据:通过append方法
- excel制作甘特图
- leetcode232 用栈实现队列
- Openlayers笔记之图片偏移的完整解决方案
- 对比Excel两个sheet的数据是否相同
- VS/MFC - 无法启动此程序因为计算机中丢失mfc140d.dll.
- ^(?:([^,]*),?){1} 的含义
- 2021-11-05 构型空间(关节空间)路径规划-1