摘要:【长文预警,建议先收藏】有了模型和多个动画以后,在Unity中如何控制它们的播放和切换呢?本文带你一站式解析Unity的Animator模块。

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

大智:“小新,还记得Unity的动画来源有哪些么?”

小新:“有Unity中制作和外部导入两种,哦对!还可以用代码写动画,不过我不会,嘿嘿”

大智:“没错,前两天我们学习的其实主要是Animation Clip的内容,也就是一个物体对应的一段动画,是整个动画系统的基本元素。今天我们要着重学习一下Animator。如果把Animation Clip比作是一段视频的话,那么Animator就是一个视频播放器,用来控制多段视频的播放、切换等等。”

Animator组件

想要在一个物体上播放动画,需要在这个物体上添加Animator组件。

Animator中有一个很重要的属性是Controller,这个属性引用了一种叫Animator Controller的资源,这种资源以文件的形式存储在工程中,文件内存储了动画的各种状态以及状态之间的切换规则。本文后半部分会细讲。

Avatar 设置使用的骨骼节点映射。

Apply Root Motion 应用根节点运动。如果不启用,动画播放时根节点会保持在原地,需要通过脚本控制物体的移动。如果启用,如果动画中有运动,动画中的运动会换算到根节点中,根节点会发生运动。(通常用于人物/动物的运动动画)

Update Mode 设置Animator更新的时机以及timescale的设置。

  • Normal Animator按正常的方式更新(随着Update调用更新,timescale减小时,动画播放也会减慢,timescale的具体含义和用法后续会详解)
  • Animate Physics Animator会按照物理系统的频率更新(根据FixedUpdate调用更新,后续会详解),适用于物理交互,例如角色加上了物理属性可以推动周围的其他物体。
  • Unscaled Time 根据Update调用更新,无视timescale。一般用于UI界面,当你使用timescale暂停游戏时,界面保持正常动画。

Culling Mode 裁剪模式

  • Always Animate 动画一直运行,即使物体在屏幕外被裁剪掉并没有渲染
  • Cull Update Transforms 当物体不可见时,禁用Retarget、IK、Transforms的更新(后续动画进阶模块会细讲)
  • Cull Completely 当物体不可见时,完全禁用动画

Animator Controller

Animator Controller是Animator组件必须的资源,这种资源以文件的形式存储在工程中,文件内存储了动画的各种状态以及状态之间的切换规则。

通常一个物体上有不止一段动画,使用Animator Controller可以很容易地管理各段动画以及动画之间的切换。比如角色身上有走、跑、跳、蹲的动画,使用Animator Controller可以很容易管理它们。不过,即使只有一段动画,仍然需要给动画物体添加Animator组件才能播放动画。

大智之前讲过可以使用PlayableAPI绕过Animator Controller来播放动画,感兴趣的话可以去看一下

Animator Controller中使用了一种叫State Machine(状态机)的技术来管理状态以及状态之间的切换。

StateMachine 状态机

状态机由State(状态)和Transition(转换)组成。State代表一个状态,在Animator Controller中一个State可以包含一段动画、一个子状态机或一个混合树(后面会细讲)。Transition用来设置状态之间的切换条件,一般会有一个或多个条件,用于从一个状态切换到另一个状态。

在Animator窗口中,可以可视化看到State以及Transition。

创建Animator Controller

创建Animator Controller资源有如下几种方式:

  • 在Unity中创建Animation Clip时,如果选中的GameObject上没有Animator组件,会自动添加Animator组件并在工程中创建一个Animator Controller文件(和Animation Clip文件同目录)。
  • 将任意Animation Clip拖到一个物体上时,如果拖到的物体上没有Animator组件,会自动添加Animator组件并在工程中创建一个Animator Controller文件(和Animation Clip文件同目录)。
  • 可以在Project窗口中手动创建Animator Controller文件,如下图所示:

编辑Animator Controller

双击Animator Controller文件,可以打开Animator窗口,编辑该文件。

今天我们先简单学习一下如何将导入的动画播放出来,后续的动画进阶模块会更详细讲解Animator Controller中的高级功能。

在Project窗口中直接创建Animator Controller时,其中是不包含任何动画的。如下图所示:

图中包含三个节点:

Entry 入口。动画状态机会从这个节点开始,根据Transition进入一个默认State。

Any State 任意状态。用于从任意状态转换到特定状态。比如射击类游戏中,如果被子弹打中后,不管当前处于什么状态,都会倒地死亡。

Exit 退出状态机。一般用于嵌套的状态机的退出(后面动画进阶模块会讲)。

添加状态

可以在空白处右键添加Empty State,也可以将Animation Clip文件拖到Animator窗口中添加一个State。

如果当前在Project窗口选中了一个Animation Clip,也可以通过上图的From Selected Clip创建一个State,不过还是直接将Clip拖到Animator中创建State更简单,如下图所示。

第一个创建的State默认是橘黄色的,代表是默认状态。有一条黄色的箭头从Entry指向橘黄色的State。Animator组件会在一开始播放New State,如果New State中有动画,也会播放对应的动画。

这时候如果你Play这个场景的话,设个物体就会播放默认State的动画。

State设置

每个State可以包含一段Animation Clip,处于该State时Animator组件所在的物体会播放该动画。选中一个State时,在Inspector中可以看到如下内容:

Motion 可以设置一个Animation Clip,如果是从Animation Clip创建的动画,这里应该已经有动画了,你也可以从工程中选择动画。

Speed 动画的播放速度

Multiplier 乘数,可以使用一个参数来控制动画的播放速度,动画最终的播放速度会是Speed * Multiplier。后面会讲解Animator的参数以及如何在代码中控制参数。

Normalized Time 单位化时间,范围是0-1,需要使用参数控制。

Mirror 镜像动画。也可以使用一个参数控制。

Cycle Offset 循环偏移量。可以用来同步循环的动画。偏移量使用的是单位化时间,范围是0-1。也可以使用参数来控制。

Foot IK 只用于人形动画。角色的脚是否使用反向动力学。

Write Defaults 是否初始化该State没有用到的参数为默认值。

Transitions 该状态参与的状态转换。下面会细讲。

Parameters 参数

上面我们提到了参数的概念,那么参数是什么呢?

Animator Controller中的参数可以作为控制transition切换的条件,也可以控制上面可以参数化的属性比如State中的几个属性。

Animator Controller的参数可以通过代码进行控制,进而控制整个Animator状态机的运转。

参数共有4种类型:

  • Int 整数类型
  • Float 浮点数(小数)类型
  • Bool true或false(真或者假,用于逻辑判断),界面上显示为复选框
  • Trigger 触发器,与Bool有点类似,但是transition在使用这个参数后会被自动设置为false状态。界面上显示为一个圆形按钮。

Transition

Transition代表状态之间的切换条件,一般会有一个或多个条件,用于从一个状态切换到另一个状态。

添加Transition

在一个State上右键,在弹出菜单中选择Make Transition,可以创建一个到其他State的Transition。

点击代表Transition的箭头,可以在Inspector上看到这条Transition的具体情况。选中Transition的源State(从哪个State出发),也可以在State的Inspector中看到这条Transition的具体信息。

Transitions 显示当前选中的Transition。后面有两个复选框包括Solo和Mute。

  • Solo 如果两个State之间有多条Transition,勾选这个选项后,只有选中Solo的Transition生效。其他Transition会被禁用。

  • Mute 勾选这个选项后,该条Transition会被禁用。如果同时选中了Solo和Mute,Mute会优先生效。

Name Field 名称框。如上图所示,可以给Transition命名,用于区分两个State之间的多个Transition时非常有用。

Has Exit Time 是否有退出时间条件。退出时间是一种特殊的transition条件,它没有依赖参数(下面会讲),而是根据设置的退出时间点作为条件进行状态转换。

Settings transition的一些参数设置。

  • Exit Time 如果勾选了Has Exit Time,该参数是可以设置的,设置动画退出的单位化时间。例如设置为0.75,代表动画播放到75%时为true,如果没有其他条件,会直接切换到下一个State。

    如果exit time小于1,那么state每次循环到对应位置的时候(不管动画是否设置为循环,state总是循环的),该条件都会为true。比如第一次播放到75%,第二次播放到75%……时退出条件都会为true。

    如果exit time大于1,该条件只会检测一次。比如exit time为3.5,state的动画会在循环3次后,在播放到第4次的50%时为true。

  • Fixed Duration 勾选时,下方Transition Duration参数的单位是秒,不勾选时,参数会作为一个百分比。

  • Transition Duration transition的过渡时间。两个状态在转换时,一般不会瞬间从一个状态转换到另一个状态,而是会经过平滑混合,这个属性就是设置了平滑混合的时间。可以从下图的两个蓝色箭头看出转换的时间。

  • Transition Offset 目标状态开始播放的时间偏移。比如设置为0.5,则转换到下一个State时,会从50%的位置开始播放。

  • Interruption SourceOrdered Interruption 这两个参数可以用来控制transition的打断。下面会进行详解。

Transition图

上面的参数不仅可以手动修改数值,也可以通过Transition图预览、修改。

Conditions 条件

一个Transition可以有一个条件,也可以有多个条件,甚至没有条件。

如果Conditions中没有条件,但是勾选了Has exit time,那么exit time会被作为state退出的条件,到达exit time时,会切换到下一个state。

如果有一个或多个条件,需要同时满足这些条件才能切换下一个state。

一个条件可以是:

  • 相等/不相等判断,一个参数等于/不等于一个常量时为true(int,float,bool类型参数)
  • 比较判断,一个参数与一个常量的比较结果(int,float类型参数)
  • 触发器,触发器激活时为true

如果Has Exit Time勾选了,并且transition还有一个或多个条件,那么transition需要同时满足到达exit time同时条件全为true,才会切换到下一个state。

一个transition至少要有一个条件(Has Exit Time可以作为一个条件),否则transition会被忽略。

【选读】Transition Interruption

之前我们提到了Interruption SourceOrdered Interruption 这两个参数可以用来控制transition的打断。那么究竟什么是transition打断呢?

一般情况下,动画系统的transition是不能打断的:一旦transition开始从一个state切换到另一个state,没有打断的方法。就像乘坐跨大西洋航班的乘客一样,你舒适地坐在座位上,直到到达目的地,无法改变主意。对于大多数用户来说,这很好。

但是如果你需要对transition进行更多控制,可以通过多种方式配置动画系统来满足需求。如果你对目前的目的地不满意,你可以跳进飞行员的座位,在飞行途中改变计划。这能带来更灵活的动画控制,但也很有可能迷失在复杂的打断中。

我们通过几个例子来深入探索一下打断。从一个相当简单的状态机开始,这个状态机具有四个状态,标记为A到D,并且使用trigger作为每个transition的条件。

默认情况下,当A到B的切换触发后,状态机开始切换到B,在切换到B之前无法被改变。但是,如果将A->B的transition的interruption source属性从None切换到Current State,A到B的切换就可以被A上的一些触发器中断。

为什么只有一些呢?因为Ordered Interruption属性默认也会被勾选。这意味着只有优先级大于当前的transition才能打断。选中State A,在Inspector中查看,我们看到A -> C的优先级高于 A -> B,那也意味着只有A -> C能打断A -> B的转换。

如果我们激活A->B的trigger,然后立马激活A->D的trigger,A到B的transition不会被打断。但是,如果我们激活A->B的trigger,然后立马激活A->C的trigger,A到B的transition会被打断,转而切换到C。

在动画系统内部,会记录下被打断时的动画的状态,然后从打断的状态混合到新的目标动画。

如果不勾选Ordered Interruption属性,会发生什么情况呢?A->C 和 A->D 都能打断 A -> B 的transition了。但是,如果在同一帧激活了A->C和A->D的trigger,A->C仍然会优先激活因为A->C的优先级更高。

如果将A -> B的interruption source属性改为Next State,也就是下一个状态。A->C 和 A->D就不能打断A -> B了。如果我们激活A->B的trigger,然后立马激活B->D的trigger,A到B的transition会被打断,转而切换到D。

B上的Transition的顺序也有影响。但是这时候Ordered Interruption属性就无法勾选了(因为A -> B是在State A上不在State B上,不参与B的排序)。B上transition的顺序会决定同时触发时,会使用哪一个transition。例如下图的排序,如果B->D 和B->C在同一帧被触发,B->D的transition会被执行。

如果想完整控制,我们可以设置interruption source属性为Current State Then Next State或Next State Then Current State。设置为这两个值时,State A和State B上的transition都会被考虑在内。例如设置如下,选中了Current State Then Next State:

如果A到B切换时,同时激活的A->C, A->D, B->C和B->D,会发生什么情况?

如果选中了Ordered Interruption,那么首先可以忽略A->D(因为比A->B)的优先级低。然后先考虑Current State A,那么A->C会胜出,甚至不用考虑Next State B了。

如果同样的配置,只激活了B->C 和 B->D,那么B->D会胜出,因为B->D的优先级比B->C更高。

小结

上面我们只使用了A->B一种情况作为例子进行了讲解,其他的中断都是类似的,只需要根据他们自身的规则即可。

有一点很重要需要记住的是:不管打断发生了几次,只要transition没有完成,source state会一直不会变。比如A->B被B->C打断,又被C->D打断,transition未完成前source state会一直是A。Animator.GetCurrentAnimatorStateInfo()也会返回State A。

简而言之,transition中断功能很强大,并提供了很大的灵活性,但会变得非常混乱。因此,合理地使用transition中断,而且一定要在编辑器中多进行测试。

总结

今天讲了Animator组件,希望你能记住一下几点:

  • 如果把Animation Clip比作是一段视频的话,那么Animator就是一个视频播放器,用来控制多段视频的播放、切换等等。
  • Animator Controller就是一个剧本,用来指导视频播放器如何播放多段视频。

今日思考题

大智:“导入Standard Assets中的Character包,看看里面的Animator Controller是如何设置的。”
小新:“好嘞~”
大智:“收获别忘了分享出来!别忘了点击右下角请好友看免费分享给你的朋友,也许能够帮到他。”

扩展阅读

  • Unity动画系统详解1:在Unity中如何制作动画?
  • Unity动画系统详解2:如何导入使用外部的动画?
  • 【建议收藏】找不到免费的角色动画?来试试mixamo
  • 2018.1之后Standard Assets如何安装?
  • 5分钟制作过场动画
  • 5分钟入门Cinemachine智能相机系统
  • Unity编辑器录屏神器:Unity Recorder

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


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

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

别走!点赞收藏哦!

好,你可以走了。

Unity动画系统详解3:如何播放、切换动画?相关推荐

  1. Unity动画系统详解10:子状态机是什么?

    摘要:除了使用Layer还有没有更好的组织状态的方式呢?感觉一个Layer里面状态多的时候,还是很显得很乱. 洪流学堂,让你快人几步.你好,我是跟着大智学Unity的萌新,我叫小新,这是复(yu)习( ...

  2. Unity动画系统详解9:Target Matching是什么?

    摘要:在游戏中,经常有这种情况:角色的手或者脚需要在特定时间放在特定的位置.比如角色需要用手撑着跳过一个石头或一堵墙,或者跳起抓住房梁.Target Match就是让动画的特定片段去匹配特定的位置. ...

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

    摘要:"Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树." 洪流学堂,让你快人几步.你好,我是跟着大智 ...

  4. unity velocity_Unity动画系统详解5:BlendTree混合树是什么?

    摘要:"Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树." 洪流学堂,让你快人几步.你好,我是跟着大智 ...

  5. T4M插件放入unity后怎么找不到_Unity动画系统详解4:如何用代码控制动画?

    摘要:通过上一篇咱们知道了播放动画需要使用Animator,那么如何用代码控制动画呢? 洪流学堂,让你快人几步.你好,我是跟着大智学Unity的萌新,我叫小新,这几周一起来复(yu)习(xi)动画系统 ...

  6. Unity动画系统详解4:如何用代码控制动画?

    摘要:通过上一篇咱们知道了播放动画需要使用Animator,那么如何用代码控制动画呢? 洪流学堂,让你快人几步.你好,我是跟着大智学Unity的萌新,我叫小新,这几周一起来复(yu)习(xi)动画系统 ...

  7. Unity动画系统详解8:IK是什么?

    摘要:IK是Inverse Kinematic的缩写,也就是反向动力学.是根据骨骼的终节点来推算其他父节点的位置的一种方法.比如通过手的位置推算手腕.胳膊肘的骨骼的位置. 洪流学堂,让你快人几步.你好 ...

  8. Unity动画系统详解6:如何做好角色的移动动画?(Root Motion详解)

    摘要:Root Transform是body transform在Y平面上的投影,并且是运行时计算的.每一帧Root Transform的变化实时计算.然后Transform的变化会被应用到GameO ...

  9. T4M插件放入unity后怎么找不到_Unity动画系统详解6:如何做好角色的移动动画?(Root Motion详解)

    摘要:Root Transform是body transform在Y平面上的投影,并且是运行时计算的.每一帧Root Transform的变化实时计算.然后Transform的变化会被应用到GameO ...

最新文章

  1. 机器学习-线性回归与梯度下降
  2. MATLAB可视化实战系列(四十)-基于MATLAB 自带手写数字集的CNN(LeNet5)手写数字识别-图像处理(附源代码)
  3. 苹果CMS的V10版本后台登录一直提示验证码错误的解决方案
  4. 美团点评Kubernetes集群管理实践
  5. vs设计窗口不见了_碳纤维的巅峰:VS沛纳海616V3
  6. 开工大吉:Oracle 18c已经发布及新特性介绍
  7. ambari mysql 密码_Ambari 切换 mysql 数据库
  8. WebView详解与简单实现Android与H5互调
  9. mysql 存储过程 条件_如何在MySQL存储过程中正确实现条件?
  10. 查看进程动态:top
  11. 实验一matlab编程基础,实验一、MATLAB编程基础及典型实例.doc
  12. 360浏览器保存的html没有图标,电脑360浏览器图标不见了怎么办
  13. ACM MM ECCV 2022 | 美团视觉8篇论文揭秘内容领域的智能科技
  14. TIdTCPClient
  15. 关于CH552G单片机连接电脑和烧录程序的细节总结
  16. 项目经理之新任项目经理的五项修炼
  17. 如何用Python+统计学,进行数据分析
  18. 傅里叶缩写及涵义整理
  19. [转载备用]微信直播的优势及微信直播搭建过程(点赞:主播妹子有点靓哦)
  20. toolbar wpf 按钮带文字_Tob设计:中台设计组件按钮

热门文章

  1. 如何成为一名成功的软件工程师
  2. 嵌入式单片机及外设(硬件)知识基础二
  3. 【uniapp】小程序中进行公众号授权
  4. FITC标记的大鼠抗小鼠CD11b抗体,FITC Rat Anti-Mouse CD11b
  5. 5644: C实验:复读机
  6. 无人驾驶:制作鸟瞰图,路径规划,路径跟踪,调试摄像头,测速度,测角度
  7. matlab 能控性判别矩阵,实验三利用matlab分析能控性和能观性
  8. linux 端口转发软件,linux端口转发神器Socat一键配置脚本
  9. 中后台学习笔记 – 数据权限
  10. matlab毕业论文(部分代码)