@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一样使用它们。
Multiple Sprite
接着,我们在Hierarchy列表中创建一个Empty GameObject,将其命名为Player后,在它下面创建一个名为Character的Empty GameObject并将char_hero_beanMan切割得到的图片都拖拽到Character下。
Player的结构
为了让Character下各个Sprite都能正常显示,我们还需要创建一个名为Character的Sorting Layer,该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的结构
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)即可。
AlienShip的结构
创建怪物的动画
首先,我们在Animation和Animator文件夹下都创建一个名为Enemy的文件夹用于保存怪物的动画和状态机。然后打开Animation Editor,在Hierarchy窗口选中AlienShip创建一个名为AlienShip.anim的动画,并将AlienShip.controller移动到Animator\Enemy文件夹下。创建完毕后,我们为AlienShip添加char_enemy_alienShip的Rotation为动画控制属性,然后添加关键帧。
AlienShip关键帧
为了使动画在循环播放时顺畅播放,不产生明显的停滞感,我们不能在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这两个动画控制属性,然后添加关键帧。
AlienSlug关键帧
因为在眨眼和伸缩尾巴时,有短暂的停顿并不会影响动画效果,因此,所有的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,所以添加的关键帧属性值参见下图。
Idle动画添加的关键帧
创建完毕后,我们点击Create New Clip,创建一个名为Walk.anim的动画并将其保存在Animation\Player文件夹下。
创建新动画
创建完毕之后,我们为Walk动画添加动画控制属性和关键帧。因为该动画精细程度要求不高,我们可以先将采样率从60减少到5,再添加动画控制属性。具体添加的动画控制属性见下图。
Walk动画的控制属性
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动画的控制属性
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帧处添加了一个关键帧,因此添加的关键帧属性值参见下图。
Shoot动画添加的关键帧
最后,我们为角色创建和死亡相关的动画。首先新建Death.anim的动画并将其保存在Animation\Player文件夹下。创建完毕之后,我们为Death动画添加动画控制属性和关键帧。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涉及到的动画控制属性较多,具体有哪些动画控制属性参照下图。
Faliing动画的关键帧
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。
制作Prefab
后言
至此,创建角色和怪物动画的所有工作都已经完成。在制作动画的过程中,读者可以根据自己的喜好调整参数。最后,本篇文章所做的修改,可以在PotatoGloryTutorial这个仓库的essay3分支下看到,读者可以clone这个仓库到本地进行查看。















网友评论