Unity动画系统详解5:BlendTree混合树是什么?

摘要:“Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树。

洪流学堂,让你快人几步。你好,我是跟着大智学Unity的萌新,我叫小新,这几周一起来复(yu)习(xi)动画系统。

“智哥,我用Animator做了一个人物移动的状态机,怎么看怎么不顺眼,这也太复杂了,你来看看?”

小新做的人物移动的状态机

“哟,这不是挺规整的嘛,我看起来挺顺眼的,哈哈哈”

“去去去,我这光一个走路的就得搞这么复杂,而且还没法斜着跑,我这做一个动画,这得多少个状态啊”

“emmm,我这有一个秒招,不知道你想学不想学?”

“那当然想学了,看我每天学习的热情多么高涨”

“那你先带我去把晚饭解决了”

“哎呀,咱们点个外卖,我已经等不及了,吃饭这都不重要”

“那也成,给我来个10斤的龙虾,点好了再来找我”

小新花了30秒搞定外卖,“快快快,开始上课!”

“看你小子猴急的,以后能成大器,嘿嘿”

BlendTree 混合树

“Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树。

“混合树和Transition中的混合有啥区别呢?”

“混合树和Transition中的混合不同,**Transition中的混合只是在两个State转换时,在给定的时间内进行混合,避免动画切换过于突兀。而混合树中的混合,是时时刻刻进行不同程度的混合。**比如你的角色有站立、走、跑三个动作,走路的速度是2m/s,跑的速度是5m/s,那你想让角色的速度是3m/s,这时候怎么办?这时候用混合树就能很简单地解决。”

“听起来很厉害,那你用我的这个移动的例子给我讲讲怎么搞呗?”

“不要着急,这时候你应该先去看看混合树的文档,自己试试,看看会遇到什么问题”

“好,那我先去看看文档”

“嗯,对了,我的大龙虾呢?”

“嘿嘿,大龙虾没有,不过给你点了个龙虾饭,看我够意思吧”

“哎,凑活吧,以后再让我教你可就难啦”

小新回到自己的房间,开始学习混合树的文档,并且记了笔记。

创建混合树

在Animator窗口的空白处右键,Create State > From New Blend Tree,双击这个节点可以进入混合树图。

混合树有3种类型,在右边的Blend Type中可以设置。分别为:

  • 1D
  • 2D
  • Direct

1D混合

1D混合是根据一个参数进行动画混合。

1、首先要设置用于混合的参数,也就是从Animator的Parameters中的选择一个参数。

2、添加动画:可以点击小加号按钮,或者在Blend Tree节点上右键Add Motion。点击后会在Motion列表中添加一个条目,可以将Animation Clip拖进来。

添加完动画,整个混合的样子:

最上面的图显示了参数对每个动画的影响。每个动画显示为一个蓝色的三角形。如果点击这个三角形,会在下面的动画列表中高亮一下。**每个三角形的顶角位置定义了参数在该位置时,会完全使用这个动画,这个值也叫做该动画的阈值(Threshold)。**比如上图中的run动画,阈值是0.5,在混合图的中心位置。

图中的红线代表了参数的数值,主要是用来预览调试。可以拖动红线,在下面预览窗口观察动画式如何混合的。

注意点播放按钮,可以预览动画播放的状态

参数范围

上图中,左右两个数字代表了参数的范围。点击数字可以变成输入框修改,也可以在数字上拖拽调节。修改时会影响到第一个动画和最后一个动画的阈值。

Threshold 阈值

修改动画对应的阈值可以直接拖拽对应的蓝色三角形。如果没有勾选Automate Threshold(自动计算阈值),也可以在阈值编辑框中直接输入数值。选中Automate Threshold(自动计算阈值)时,阈值会自动在最小值和最大值之间自动平均分布。

下面有一个Compute Thresholds下拉框,使用这个下拉框,可以根据动画中的数据,自动计算阈值。数据包括:speed(速度),velocity x、y、z(xyz三个轴分别的速度),angular speed(转动速度,单位是角度或弧度)。这些数据如何知道呢?

比如:走路动画的速度是1.5m/s,跑的速度是4m/s,如果选择Compute Thresholds中的Speed,walk动画的阈值会被设置为1.5,run动画的阈值会被设置为4。

Time Scale

通过动画速度这一列(图标是一个表)可以调节动画的播放速度,比如你想让跑步的动画播放速度变为原来的2倍,可以设置为2。

**Adjust Time Scale > Homogeneous Speed ** 可以将动画的速度调整对应到参数的最小值和最大值,但是保持动画的初始相对速度。
这句话看得我欲生欲死,得问问大智是什么意思

按钮可以将动画的播放速度调整到动画列表中所有动画速度的平均值。

Mirroring 镜像

上面复选框可以左右镜像一个humanoid类型的动画Clip。这个功能可以使用同一个动画创建出来两个方向的动画,可以节省一倍的存储空间和内存。

比如一个向左走的动画,通过镜像可以创建出一个向右走的动画。

难点解析

这时候门铃响了,“先生,您的龙虾饭到了。祝您用餐愉快,给个5星好评呗~”

“大智,吃饭前问你两个问题呗”

“不行,我得看看这个龙虾饭到底怎么样”

说着大智以迅雷不及掩耳之速拆开了包装,吃了几口。

“嗯,还不错,心情大好,来问吧!”

“我选的,能不好吃嘛!”

“第一个问题:自动计算Threshold的时候,那些动画的速度啊,旋转速度怎么知道啊?”

“选中一个Animation Clip,你可以看到这些数据,比如这个:”

“第一行是这个动画在xyz轴上的速度,第二行是旋转速度。”

“原来在这,这里我还没仔细看过呢”

“以后会用到的”

“第二个问题:**Adjust Time Scale > Homogeneous Speed **这个到底是干嘛的,怎么我看了半天都没看明白文档中的含义?”

“我记得文档中的解释有一些难理解,其实这个按钮的作用就是:先将所有动画的平均速度算出来,然后通过调节动画的speed让所有动画的速度都一致。

“啊?真的么?我怎么看文档跟这个一点联系都没有呢?”

“不信你去试试,看看是不是我说的这样”

“OK,你赶紧吃饭吧,我要继续去看了,2D混合树还没看呢”

小新回到房间继续学习2D混合树,下面是他做的学习笔记。

2D混合树

2D混合树可以根据2个参数进行动画混合。

最终效果展示

2D混合树有三个选项,分别是:

  • 2D Simple Directional(2D简单方向):当你的运动代表不同的方向,如“向前走”,“向后走”,“向左走”,“向右走”,或“向上瞄准”,“向下瞄准”,“左瞄“和”右瞄“。当然了,可以在(0,0)处包含一个默认动作类似“空闲站立”或“直线瞄准”。与1D混合树不同的是,2D Simple Directional不是在同一个方向上的多个动作,比如“走”和“跑”。

  • 2D Freeform Directional(2D自由方向):动画运用有不同的方向时,也可以使用这种混合类型:可以在同一个方向上有多个运动,例如“走”和“跑”。在Freeform Directional类型中,(0,0)位置必须包含一个默认动作,如“空闲站立”。

  • 2D Freeform Cartesian(2D自由笛卡儿):当混合的2个参数代表不同的方向时使用。使用Freeform Cartesian,参数X和Y可以表示不同的概念类型,例如角速度和线速度。举个例子:“向前走不转向”,“向前跑不转向”,“向前走并右转”,“向前跑并右转”等动作。

如果角色动画包含站立、走、跑和转向,非常符合2D Freeform Cartesian这种类型。后面以2D Freeform Cartesian举例说明。

将Blend Type设置为2D Freeform Cartesian

设置Blend Type之后,首先需要两个参数控制这个Blend Tree。

在Animator中添加两个float参数:Turn和Forward分别代表转向速度和向前行进速度,然后将这两个值设置为混合树的参数(注意顺序)

注意参数的顺序

然后点击 + > Add Motion Field 添加下列动画clip到混合树动画列表。(先不管后面的值)

下面,我们可以使用Unity中提供的自动计算Pos值的功能,来自动计算混合树的阈值。

Positions详解

每一个Motion都有一个自己的位置,当参数(x,y)靠近这个位置时,这个动画就会参与混合。离得越近,这个动画的比重就越大。

选中一个Motion时,图中的蓝点会有选中的状态;同样选中混合图中一个蓝点,对应的Motion也会有选中的状态。

Motion选中状态

可以拖动混合图中相应的蓝点来修改位置,也可以直接修改Motion后面的值。

Compute Positions

Unity提供了自动计算Position的功能。

通过Compute Position下拉菜单可以选择不同的计算方式:

属性 功能
Velocity XZ 根据动画自身的速度,将velocity.x设置每个动画的Pos X,将velocity.z设置Pos Y。适合2D Simple Directional和2D Freeform Directional类型的混合树。
Speed And Angular Speed 将动画的Y轴角速度(弧度每秒)设置到Pos X,速度设置到Pos Y。适合2D Freeform Cartesian类型的混合树。

另外,还可以通过 Compute Position -> X Position FromCompute Position -> Y Position From 单独计算X或Y的值。

属性 功能
Speed 动画的速度
Velocity X 沿X轴的速度
Velocity Y 沿Y轴的速度
Velocity Z 沿Z轴的速度
Angular Speed (Rad) Y轴的角速度,单位是弧度/秒
Angular Speed (Deg) Y轴的角速度,单位是角度/秒

Rad 和 Deg 分别代表了弧度和角度,弧度π(3.1415…) = 180°
可以根据项目的需要来选择,两种都可行,但是如果X,Y的数值相差过大的话,在混合图上显示会不便于调试。

在模型的Import Settings面板可以看到动画的速度

查看动画的速度和角速度

回到我们的混合树:
参考上面的内容,我们可以使用Speed And Angular Speed来计算每个Motion的位置。

选择Compute Positions中的Speed And Angular Speed

设置完后,整个混合树如下图所示:

现在我们来测试一下,看看怎么样。

设置完毕后的效果

Preview窗口中,记得一定要点击左上角的播放,动画才会实时播放看到效果。

混合的原理

动画混合时,会根据X和Y两个值来确定混合的动画以及各自所占的比重。上面动图中我们可以看到,拖动红点时,可以看到不同的节点上面圆圈在发生不同的变化,圆圈的大小即这个动画所占比重的大小。

6个动画混合的效果
红点所在的位置代表了X和Y两个参数的值对应的位置。横轴是X,纵轴是Y。

Direct Blending 直接混合

直接混合可以直接将animator的参数映射到混合树动画的权重。这在什么时候使用呢?如果你想用参数精确控制混合的动画,而不是通过以两个参数间接控制动画的混合。

设置一个direct混合树时,motion列表中的每一个动画需要对应一个参数,用来控制这个动画的混合权重。

难点解析

“大智,这个2D混合树中的阈值和动画中的真实速度是对应关系么?”

“其实只要保持对应的相对比例就可以,并不一定要真实的速度:”

1、X,Y的值和动画的实际速度没有映射关系。我们也可以将“走”的动画的Y值设置的大一些,将跑的动画设置的小一些。但是这样设置会在表现上不符合玩家的预期,感觉怪怪的。

2、在手动调整时,只要点之间的相对位置保持不变,混合效果不会受太大的影响。

3、但是要注意在写代码的时候,要根据调整过后值的范围来设置对应的参数。

“这样调整完参数就感觉整个图好看了好多,哈哈!”

总结

“现在你知道混合树是干嘛的了吧?”
“知道了,混合树可以根据参数,混合多个动画,每个动画有不同的权重,这样就有了很多中间状态。”
“想要把混合树用好,需要多去尝试一下”
“嗯,我这就准备把我那个移动的Animator Controller改成混合树的方式呢”

今日思考题

“正好,给你布置个思考题,实现人物的前后左右走、跑的动态混合,正好也能用到你的吃鸡游戏里”
“收到!我去也!”
“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”

扩展阅读

【扩展学习】洪流学堂公众号回复动画可以阅读本系列所有文章,更有视频教程等着你!


呼~ 今天小新絮絮叨叨的真是够够的了。没讲清楚的地方欢迎评论,咱们一起探索。

我是大智(微信:zhz11235),你的技术探路者,下次见!

别走!点赞收藏哦!

好,你可以走了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章