《土豆荣耀》重构笔记(五)创建角色以及怪物的动画
@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一样使用它们
。
![](https://img.haomeiwen.com/i15775655/9b5b1c2a2ef88dca.png)
接着,我们在Hierarchy
列表中创建一个Empty GameObject
,将其命名为Player
后,在它下面创建一个名为Character
的Empty GameObject
并将char_hero_beanMan
切割得到的图片都拖拽到Character
下。
![](https://img.haomeiwen.com/i15775655/5f466a1aa50d8256.png)
为了让Character
下各个Sprite都能正常显示,我们还需要创建一个名为Character的Sorting Layer
,该Sorting Layer与其他Sorting Layer的关系如下:
![](https://img.haomeiwen.com/i15775655/5260170ca9835851.png)
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
下面。
![](https://img.haomeiwen.com/i15775655/d4473412de4fcc16.png)
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)
即可。
![](https://img.haomeiwen.com/i15775655/d84d4d55d538df03.png)
创建怪物的动画
首先,我们在Animation
和Animator
文件夹下都创建一个名为Enemy
的文件夹用于保存怪物的动画和状态机。然后打开Animation Editor
,在Hierarchy
窗口选中AlienShip
创建一个名为AlienShip.anim
的动画,并将AlienShip.controller
移动到Animator\Enemy
文件夹下。创建完毕后,我们为AlienShip
添加char_enemy_alienShip的Rotation
为动画控制属性,然后添加关键帧。
![](https://img.haomeiwen.com/i15775655/23903a097df8c7b5.png)
为了使动画在循环播放时顺畅播放,不产生明显的停滞感,我们不能在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
这两个动画控制属性,然后添加关键帧。
![](https://img.haomeiwen.com/i15775655/5611e570190a1910.png)
因为在眨眼和伸缩尾巴时,有短暂的停顿并不会影响动画效果,因此,所有的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
,所以添加的关键帧属性值参见下图。
![](https://img.haomeiwen.com/i15775655/9f04261980e60533.png)
创建完毕后,我们点击Create New Clip
,创建一个名为Walk.anim
的动画并将其保存在Animation\Player
文件夹下。
![](https://img.haomeiwen.com/i15775655/3b8d866ee874d764.png)
创建完毕之后,我们为Walk
动画添加动画控制属性和关键帧。因为该动画精细程度要求不高,我们可以先将采样率从60减少到5
,再添加动画控制属性。具体添加的动画控制属性见下图。
![](https://img.haomeiwen.com/i15775655/95fd08bc3eb543ab.png)
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
,再添加动画控制属性。具体添加的动画控制属性见下图。
![](https://img.haomeiwen.com/i15775655/54b20748ae0d365b.png)
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帧处
添加了一个关键帧,因此添加的关键帧属性值参见下图。
![](https://img.haomeiwen.com/i15775655/9993c0a7c00bd08c.png)
最后,我们为角色创建和死亡相关的动画。首先新建Death.anim
的动画并将其保存在Animation\Player
文件夹下。创建完毕之后,我们为Death
动画添加动画控制属性和关键帧。Death
动画是最为复杂的动画,涉及到的动画控制属性较多,且创建的步骤有所不同。
![](https://img.haomeiwen.com/i15775655/c4de6d6daa5e8c8f.png)
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
涉及到的动画控制属性较多,具体有哪些动画控制属性参照下图。
![](https://img.haomeiwen.com/i15775655/4ed6bb288bcbdff9.png)
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。
![](https://img.haomeiwen.com/i15775655/7a1688514a1ea6d5.png)
后言
至此,创建角色和怪物动画的所有工作都已经完成。在制作动画的过程中,读者可以根据自己的喜好调整参数。最后,本篇文章所做的修改,可以在PotatoGloryTutorial这个仓库的essay3
分支下看到,读者可以clone这个仓库到本地进行查看。