@TOC
前言
在游戏中,角色和AI的移动都需要配上相应的动画,以免让玩家产生游戏中的角色或者AI在平移的不真实感。一般来说,角色和AI的动画都会比前面介绍的游戏背景动画复杂很多,因为角色和AI的动画既需要精心编辑动画让身体各个部位的运动看起来很真实,又需要协调身体各个部位的运动。本篇文章的主要内容,就是讲述如何使用Unity制作角色和怪物的动画。
创建角色和怪物
在开始制作角色和怪物的动画之前,我们需要先创建角色和怪物。在Project
窗口打开Sprites\Character
目录,可以看到char_enemy_alienSlug
和char_hero_beanMan
并不是一张完整的图片,而是多张图片拼在一起的图集
。点击char_hero_beanMan
,在Inspector
窗口我们可以看到它的Sprite Mode
为Multiple
,这表示这张图片是多张图片拼接而成,Unity会自动帮我们切成多张单独的图片。当然,我们也可以点击Sprite Editor
来决定自己要怎么切割图片,Sprite Editor
的具体用法可见Unity的Sprite Editor。切割完成之后,点击char_hero_beanMan
右下角的三角形图标
,我们可以看到有许多张小图片以列表的形式展示出来,这些就是切割产生的图片,我们可以像使用普通Sprite一样使用它们
。
接着,我们在Hierarchy
列表中创建一个Empty GameObject
,将其命名为Player
后,在它下面创建一个名为Character
的Empty GameObject
并将char_hero_beanMan
切割得到的图片都拖拽到Character
下。
为了让Character
下各个Sprite都能正常显示,我们还需要创建一个名为Character的Sorting Layer
,该Sorting Layer与其他Sorting Layer的关系如下:
Player各个子物体的被修改的属性如下:
- Character:
*Scale
: (0.48, 0.48, 0.48)- bazooka:
Position
: (0.234, 0.394, 0)Sorting Layer
: Character,Order In Layer
: 0- body:
*Sorting Layer
: Character,Order In Layer
: 1- hat:
Position
: (-0.4, 1.43, 0),Rotation
: (0, 0, -5.724)Sorting Layer
: Character,Order In Layer
: 2- leftEye
Position
: (0.39, 0.892, 0)Sorting Layer
: Character,Order In Layer
: 3- leftFoot
Position
: (0.81, -1.63, 0)Sorting Layer
: Character,Order In Layer
: 3- leftHand
Position
: (0.937, -0.058, 0)Sorting Layer
: Character,Order In Layer
: 3- rightEye
Position
: (-0.212, 0.801, 0)Sorting Layer
: Character,Order In Layer
: 3- rightFoot
Position
: (-0.49, -1.87, 0)Sorting Layer
: Character,Order In Layer
: 3- rightHand
Position
: (-0.975, -0.386, 0)Sorting Layer
: Character,Order In Layer
: 3- tache
Position
: (-0.019, 0.173, 0)Sorting Layer
: Character,Order In Layer
: 3
接着,我们创建一个名为AlienSlug
的Empty GameObject
,然后在AlienSlug
下创建一个名为Character
的Empty GameObject
,并将char_enemy_alienSlug
切割得到的图片拖拽到Character
下面。
AlienSlug各个子物体的被修改的属性如下:
- Character:
Scale
: (0.4, 0.4, 0.4)- enemy1-eye:
Position
: (0.06, 0.59, 0)Sorting Layer
: Character,Order In Layer
: 0- enemy1-eyelid:
Position
: (-0.07, 1.07, 0)Sorting Layer
: Character,Order In Layer
: 1- enemy1-body:
Position
: (0, 0, 0)Sorting Layer
: Character,Order In Layer
: 2- enemy1-tail:
Position
: (-1.52, -1.49, 0)Sorting Layer
: Character,Order In Layer
: 1
最后,我们创建一个名为AlienShip
的Empty GameObject
,然后在AlienShip
下创建一个名为Character
的Empty GameObject
。因为char_enemy_alienShip
的Sprite Mode
为Single
,因此我们直接将这张图片拖拽到AlienShip
下的Character
下并将Character
的Scale
设置为(0.4, 0.4, 0.4)
即可。
创建怪物的动画
首先,我们在Animation
和Animator
文件夹下都创建一个名为Enemy
的文件夹用于保存怪物的动画和状态机。然后打开Animation Editor
,在Hierarchy
窗口选中AlienShip
创建一个名为AlienShip.anim
的动画,并将AlienShip.controller
移动到Animator\Enemy
文件夹下。创建完毕后,我们为AlienShip
添加char_enemy_alienShip的Rotation
为动画控制属性,然后添加关键帧。
为了使动画在循环播放时顺畅播放,不产生明显的停滞感,我们不能在KeyFrame处对Animation Curve
作平滑处理,因此这里,所有的KeyFrame的Tangent Type
我们都设置为Auto
。
AlienShip新增的关键帧的属性值如下(起始帧和结尾帧不变,
Tangent Type
都为Auto):
- KeyFrame 1:
frame
: 15,Rotation
: (0, 0, 4.8)Tangent Type
: Auto- KeyFrame 2:
frame
: 30,Rotation
: (0, 0, 0)Tangent Type
: Auto- KeyFrame 3:
frame
: 45,Rotation
: (0, 0, -4.8)Tangent Type
: Auto
接着,我们用相同的办法创建一个名为AlienSlug.anim
的动画。创建完毕后,我们为AlienSlug
添加enemy1-eyelid的Positon
和enemy1-tail的Scale
这两个动画控制属性,然后添加关键帧。
因为在眨眼和伸缩尾巴时,有短暂的停顿并不会影响动画效果,因此,所有的KeyFrame的Tangent Type
我们都使用默认的Clamped Auto
,以确保能产生一条光滑的曲线。
AlienSlug新增的关键帧的属性值如下(起始帧和结尾帧不变。
Tangent Type
都为Clamped Auto ):
- KeyFrame 1:
frame
: 20enemy1-tail的Scale
: (1.6, 1, 1)Tangent Type
: Clamped Auto- KeyFrame 2:
frame
: 30enemy1-eyelid的Rotation
: (-0.07, 1.31, 0)Tangent Type
: Clamped Auto
创建角色动画
角色的动画比较复杂,除了静止时的Idle
动画,我们还需要创建行走时的Walk
、跳跃时的Jump
、射击时的Shoot
和死亡时的Death
。我们先从最简单的Idle
动画做起。
首先,我们在Animation
和Animator
文件夹下都创建一个名为Player
的文件夹用于保存角色的动画和状态机。然后打开Animation Editor
,在Hierarchy
窗口选中Player
创建一个名为Idle.anim
的动画,并将Player.controller
移动到Animator\Player
文件夹下。创建完毕之后,我们为Idle
动画添加body的Position
属性作为动画控制属性,然后添加关键帧。因为在Idle
动画中,我们只在第30帧处
添加了一个关键帧,切所有关键帧的Tangent Type
为默认的Clamped Auto
,所以添加的关键帧属性值参见下图。
创建完毕后,我们点击Create New Clip
,创建一个名为Walk.anim
的动画并将其保存在Animation\Player
文件夹下。
创建完毕之后,我们为Walk
动画添加动画控制属性和关键帧。因为该动画精细程度要求不高,我们可以先将采样率从60减少到5
,再添加动画控制属性。具体添加的动画控制属性见下图。
Walk动画新增的关键帧的属性值如下(起始帧和结尾帧不变,
Tangent Type
都为Free Smooth + Flat):
- KeyFrame 1:
frame
: 1leftFoot的Position
: (0.15, -1.87, 0)tache的Rotation
: (0, 0, -3.25)Tangent Type
: Free Smooth + Flat- KeyFrame 2:
frame
: 2bazooka的Position
: (0.33, 0.47, 0)leftFoot的Position
: (-0.56, -1.8, 0)leftFoot的Rotation
: (0, 0, -59.081)leftHand的Position
: (1.033, 0.018, 0)rightFoot的Position
: (0.56, -1.8, 0)rightFoot的Rotation
: (0, 0, 37.936)rightHand的Position
: (-1.07, -0.386, 0)Tangent Type
: Free Smooth + Flat- KeyFrame 3:
frame
: 3leftFoot的Position
: (0.15, -1.87, 0)Tangent Type
: Free Smooth + Flat
接着,我们继续创建一个名为Jump.anim
的动画并将其保存在Animation\Player
文件夹下。创建完毕之后,我们为Jump
动画添加动画控制属性和关键帧。因为该动画精细程度要求不高,我们可以,我们可以先将采样率从60减少到10
,再添加动画控制属性。具体添加的动画控制属性见下图。
Jump动画修改的关键帧的属性值如下:
- KeyFrame 0:
frame
: 0hat的Position
: (-0.5, 1.6, 0)leftFoot的Position
: (1.07, -1.89, 0)rightFoot的Position
: (-0.73, -2.11, 0)rightHand的Position
: (-1.59, -0.58, 0)Tangent Type
: Free Smooth + Flat- KeyFrame 1:
frame
: 从10移动到5,表示动画只有0.5sTangent Type
: Free Smooth + Flat
设置好Jump
动画的关键帧之后,我们继续创建一个名为Shoot.anim
的动画并将其保存在Animation\Player
文件夹下。创建完毕之后,我们为Shoot
动画添加动画控制属性和关键帧。Shoot
动画所有关键帧的Tangent Type
都为Free Smooth + Flat
,因为Shoot
动画只在第30帧处
添加了一个关键帧,因此添加的关键帧属性值参见下图。
最后,我们为角色创建和死亡相关的动画。首先新建Death.anim
的动画并将其保存在Animation\Player
文件夹下。创建完毕之后,我们为Death
动画添加动画控制属性和关键帧。Death
动画是最为复杂的动画,涉及到的动画控制属性较多,且创建的步骤有所不同。
Death动画的创建步骤:
- 添加动画控制属性
- 删除默认生成的结尾帧动画
- 添加在第10帧处的关键帧
- 添加在第4帧处的关键帧
- 添加在第15帧处的关键帧
修改的关键帧的属性值如下:
- KeyFrame 1:
frame
: 4Character的Rotation
: (0, 0, 0)Tangent Type
: Clamped Auto- KeyFrame 2:
frame
: 10Character的Rotation
: (0, 0, 24.075)bazooka的Position
: (-4.36, 0.65, 0)bazooka的Rotation
: (0, 0, 270.688)bazooka的Scale
: (0.85, 0.85, 0.85)bazooka的Color
: (255, 255, 255, 0)hat的Position
: (-1.52, 3.21, 0)hat的Rotation
: (0, 0, -214.424)hat的Color
: (255, 255, 255, 0)leftEye的Position
: (0.39, 0.97, 0)leftFoot的Position
: (1.03, -1.25, 0)leftFoot的Rotation
: (0, 0, 18.147)leftHand的Position
: (0.77, 0.56, 0)rightEye的Position
: (-0.11, 0.79, 0)rightFoot的Position
: (-0.3, -1.6, 0)rightFoot的Rotation
: (0, 0, 5.605)rightHand的Position
: (-0.86, 0.51, 0)tache的Position
: (0, 0.22, 0)tache的Scale
: (0.8, 0.8, 0.8)Tangent Type
: Clamped Auto- KeyFrame 3:
frame
: 15Character的Rotation
: (0, 0, 65.82201)Tangent Type
: Clamped Auto
角色死亡后,还需要一个掉落的动画。首先新建Falling.anim
的动画并将其保存在Animation\Player
文件夹下。创建完毕之后,我们为Falling
动画添加动画控制属性和关键帧。需要注意的是,Falling
动画是接着Death
动画播放的,因此Falling
动画的第一帧是以Death
动画的最后一帧为基础的。此外,Falling
涉及到的动画控制属性较多,具体有哪些动画控制属性参照下图。
Death动画修改的关键帧的属性值如下:
- KeyFrame 0:
frame
: 0Character的Rotation
: (0, 0, 65.82201)bazooka的Color
: (255, 255, 255, 0)body的Rotation
: (0, 0, 0)hat的Color
: (255, 255, 255, 0)leftFoot的Position
: (1.03, -1.25, 0)leftFoot的Rotation
: (0, 0, 18.147)leftHand的Position
: (0.77, 0.56, 0)leftHand的Rotation
: (0, 0, 0)rightFoot的Position
: (-0.3, -1.6, 0)rightFoot的Rotation
: (0, 0, 5.605)rightHand的Position
: (-0.86, 0.51, 0)rightHand的Rotation
: (0, 0, 0)tache的Position
: (0, 0.22, 0)tache的Scale
: (0.8, 0.8, 0.8)Tangent Type
: Clamped Auto- KeyFrame 1:
frame
: 10body的Rotation
: (0, 0, -4.336)leftFoot的Position
: (1.06, -0.99, 0)leftFoot的Rotation
: (0, 0, 11.305)leftHand的Position
: (1.06, 0.9, 0)leftHand的Rotation
: (0, 0, 17.069)rightFoot的Position
: (-0.16, -1.91, 0)rightFoot的Rotation
: (0, 0, 6.283)rightHand的Position
: (-0.93, 0.28, 0)rightHand的Rotation
: (0, 0, -13.507)Tangent Type
: Clamped Auto- KeyFrame 2:
frame
: 20Character的Rotation
: (0, 0, 65.82201)leftFoot的Position
: (1.15, -1.43, 0)leftFoot的Rotation
: (0, 0, -8.312)leftHand的Position
: (0.95, 0.17, 0)leftHand的Rotation
: (0, 0, -17.067)rightFoot的Position
: (-0.25, -1.61, 0)rightFoot的Rotation
: (0, 0, 19.564)rightHand的Position
: (-0.94, 0.59, 0)rightHand的Rotation
: (0, 0, 6.41)Tangent Type
: Clamped Auto
制作Prefab
创建完所有角色和怪物的动画之后,我们还需要做一点小小的收尾工作。首先,我们在Assets
文件夹下都创建一个名为Prefabs
的文件夹,然后在Prefabs
文件夹下都创建一个名为Character
的文件夹,用于存放角色和怪物的Prefab。接着,我们将Player
、AlienSlug
和AlienShip
这三个GameObject从Hierarchy
窗口中拖拽到Project
下的Assets\Prefabs\Character
文件夹中,将它们做成Prefab。
后言
至此,创建角色和怪物动画的所有工作都已经完成。在制作动画的过程中,读者可以根据自己的喜好调整参数。最后,本篇文章所做的修改,可以在PotatoGloryTutorial这个仓库的essay3
分支下看到,读者可以clone这个仓库到本地进行查看。
参考链接
- Unity的Sprite Editor
- Prefabs
- Creating Prefabs