一、动画的基本概念
1、帧
在古代,一幅字画叫一帧,而在计算机中,每次渲染完毕一幅画面并显示出来,这一幅画就是一帧。
连续切换的帧就形成了动态的画面。每秒刷新帧的次数称为频率,单位是FPS(Frames Per Second,帧/秒),也可以简称为"帧"。传统电影每秒显示24帧就可以保证良好的动态效果。由于游戏与电影显示原理的不同,游戏至少需要30帧才能感到流畅,而要保证良好的视觉体验则最好是60帧。在电子竞技领域中,也会追求更高的帧率,以获得比赛中的优势。
我们普遍希望帧率尽可能稳定,但在游戏运行过程中,设备不一定能维持稳定的帧率。当运算负载较高时,Unity就会降低画面和逻辑的更新次数
2、帧动画
帧动画是最古老、也是最容易理解的一种动画技术。它是事先准备好动画中的每一帧画面,然后依次播放。
优点:简单直接、技术门槛低,美术设计师在一定范围内可以自由发挥
缺点:美术制作的工作量较大,占用的存储空间也大(每一帧都需要完整保存),目前主要用于2D游戏
3、3D骨骼动画
早期的3D动画是由设计师编辑模型各部分的位置、旋转等,直接制作出动作。这有点类似于橡皮泥手工动画,要让人物走路就要不断调整头、身体、手臂、和腿等各个部分的位置,这导致最初的3D动画工作量大,而且很难做出真实的人类动作。
随着技术的发展,出现了"骨骼动画"这一技术。骨骼动画思想简单来说,是将人物模型与一个类似火柴棍组成的骨架绑定在一起,每一段火柴棍(骨骼)关联着模型的一部分,这样只需要移动和旋转骨架,人物就会跟着做出各种动作了。这一技术不仅节省了工作量,而且动作效果也更加自然。
另外,同一套骨骼数据可以应用于体型相近的不同角色模型上这样就可以批量地制作更多的角色。实践中甚至可以将一套骨骼和动画适配到另一套不同的骨骼模型上,这称为"重定向"。
Unity对3D动画、3D骨骼动画君哦与较好的支持,如FBX文件(一种常用的3D模型和动画文件格式)。
在Project窗口中选定FBX文件,,可以在Inspector窗口内看到导入设置,导入设置具有Model(模型)、Rig(骨骼绑定)、Animation(动画)、和Materials(材质)4个选项。其中的Rig选项中,可以选择的动画类型为None(无骨骼)、Legacy(旧版系统)、Generic(通用型)、和Humanoid(人形),目前主要使用后两者。如果是人形骨骼模型,则选择Humaniod,在其他情况下(没有骨骼或不是人形角色)都可以选择Generic选项。Unity对常用的人形骨骼有优化,功能更多,使用也更方便。
4、2D骨骼动画
随着骨骼动画的发展,人们发现2D动画其实也可以借用骨骼动画技术。思路是将2D角色身体的各个部分切割开,做成独立的图片,然后绑定一个2D的"火柴"组成的骨骼,通过调整骨骼,也可以让2D角色活灵活现地动起来。这样可以提高效率和资源利用率。
目前Unity对2D骨骼动画也有较好的支持,可以借助官方扩展包2D Animation直接制作2D骨骼动画,也可以使用更专业的2D骨骼动画软件,如Spine和Dragonbones借助相关插件导入Unity中使用
二、动画融合
3D骨骼动画和2D骨骼动画都有一个共同的特点:动作被抽象画、数据化了,计算机能够表示帧与帧之间的联系,甚至能够计算出两帧之间的过渡状态。动画设计师只需要制定一个动作中的关键几个帧(关键帧),其他的帧(过渡帧)可以利用数学算法进行插值计算(线性插值或其他插值算法)。
以此类推,不仅同一个动作的各个关键帧之间可以自动计算过渡帧,而且不同动作之间也可以计算过渡帧。再进一步,如果动画设计师提供了"慢走"和"快跑"两个动作,甚至还可以通过插值计算出慢跑、中苏跑等更多介于慢跑和快爬之间的动作。这种在不同动作之间自动计算过渡状态的技术称为"动画融合"。
Unity对动画融合有很好的支持,在动画状态机中有专用的融合树(Blend Tree),它支持一个或两个维度的动画融合。"两个维度"指的是两种运动方式,如常用的"转身"和"前进"就是两个维度,利用Blend Tree可以混合出慢走并快速左转,或者快走并慢速右转等不计其数的动作。
⚠️:在帧动画中,每一帧都是相对独立的。帧动画的数据没有抽象画、数据化,就不肯能进行动画融合。因此,如果采用帧动画,就不用考虑动画融合。
三、动画状态机
目前,几乎所有的Unity游戏在制作动画时都要用到动画状态机(Animator),动画状态机目前已经是游戏开发的标准配置。
但是,理论上来说动画状态机并不是必须的。特别是对采用帧动画制作的游戏来说,帧动画本质就是图片的切换,那么只要及时切换图片,自然就能正常播放动画。因此,用脚本直接修改图片也并无不可,比一定非要使用动画状态机。
只是在实际游戏开发中,利用动画状态机可以统一动画制作思路,包括2D动画、3D动画、骨骼动画和动画融合等。因此,Unity逐渐摒弃了其他的动画管理方法而统一用动画状态机组件管理所有动画。
理解动画状态机
要理解使用"动画状态机"的必要性,必须思考一个问题:假设有站立、下蹲、走/跑和跳跃4种动画,那如何变成来描述动画状态,以便在不同的动画之间切换?其初步思考结论如下:
- 在地面上速度为0时,站立。这是默认动画
- 在站立状态下速度大于0,切换为走或跑的动画,根据移动速度帧切换速度。
- 在站里状态下跳跃,切换为跳跃动画
- 在走/跑状态下跳跃,也切换为跳跃动画
- 在跳跃状态下落地,切换为站立动画。如果速度部位0,站立动画会立即切换到走/跑动画
- 在站立状态下下蹲,切换为下蹲动画
- 在下蹲状态下站立,切换为站立动画
以此类推,逐个分析清楚每一个动画状体及转移条件,就可以得出动画切换的思路。"思路"有一种明显的模式:当前处于某个状态,如果发生某件事,就切换到另一个状态。
这种思路在编程中极其有用,有一个专门的名称——状态机(State Machine)。虽然本文是在动画系统中初次提到状态机,但实际上状态机的应用非常广泛,包括在游戏逻辑框架和AI系统中都经常能用到。大学生第一次了解到通常是在学习计算机网络时。
状体🐔在任意时刻都具有一个"当前状态",并且默认会保持着一状态,只有在满足某个条件时,才会切换到另一个状态。也就是说,状态机有两个要素:状态和状态转移。
用脚本直接实现状态机,只需要用一个变量保存当前状态,根据游戏逻辑切换状态即可。而对于动画系统来说,将状态🐔思想应用于管理动画状态极为合适,具有嗯好的通用型。Unity所提供的动画状态机组件,就是专门用来管理动画状态,以及动画之间的切换和过渡的。
四、根骨骼动画
让逻辑系统控制角色的运动,而动画系统只是单纯地做表现,但从技术角度看,这种方式比较简单,也不容易出bug。但随着3D游戏的不断发展,有一个问题一直困扰着游戏设计师——角色的动画与移动速度很难匹配。
以跑步为例,如果动画快一些,实际移动慢一些,会感觉角色在走"太空步";如果动画慢一些,实际移动快一些,就会感觉角色在"飘"。虽然理论上来说总能找到一个合适的参数。让移动速度能够完美地与动画配合,让角色走的更真实,但实际上要做到这一点并不容易。
而且,现代游戏具有攀爬、斩击、移动射击和冲刺等越来越多逼真的动作,让动画与移动配合的问题变得更加复杂。要想彻底解决这一问题,只能让动画设计师直接控制角色的移动。
Animator的应用根骨骼动画(Apply Root Motion)选项就是为了解决这一问题而存在的,勾选它意味着开启跟骨骼动画功能,物体会根据动画自带的位移改变自身的位置。而这个位移度是由动画设计师决定的(直接记录在动画中),而非程序控制的。
但是开启根骨骼动画功能需要以下三个条件,缺一不可:
- 动画在制作时,本来就带有位移信息
- 导入动画文件时,正确导入了根骨骼动画信息
- Animaotr中勾选了Apply Root Motion选项
对于使用了根骨骼动画的游戏来说,角色控制器编写思路也会发生变化。由于通过控制动画状态机就能控制角色的移动,那么直接移动角色位置的代码就需要删除或做出修改