《土豆荣耀》重构笔记(十六)随机生成不可交互物体
前言
  在前面的文章中,我们提到,为了不让游戏背景那么一成不变,显得更有动感一点,我们通常需要加入一些不能与游戏内的元素发生交互的背景动画。但有一些作为背景动画的物体并不是在进行重复运动的,我们不能简单地为制作循环播放的动画,而是要使用Generator随机生成它们。
制作不可交互物体的动画
  在游戏里,一共有移动的出租车、移动的巴士和飞翔的天鹅这三种不可交互的物体,我们先来制作出租车的动画。
出租车动画的制作步骤如下:
- 将
Assets\Sprites\Props下Cab图片切割得到的Cab拖拽到游戏场景中,接着设置SpriteRenderer组件的Sorting Layer为Background,并设置Order In Layer为3 - 将
Cab图片切割得到的Wheels拖拽到游戏场景中的Cab物体下成为其子物体,接着设置Wheels的Position为(0, -0.8, 0),然后设置SpriteRenderer组件的Sorting Layer为Background,并设置Order In Layer为4 - 打开
Animation窗口,选中Cab物体,然后点击Create创建一个名为Cab.anim的动画文件,并将其保存在Assets\Animation\Environment文件夹下 - 将
Assets\Animation\Environment文件夹下的Cab.controller移动到Assets\Animator\Environment文件夹下 - 点击
Animation窗口的红点按钮,开始为Cab.anim添加关键帧,添加的关键帧信息如下:Cab.anim的关键帧:第一帧:frame: 0Cab:Rotaition: (0, 0, 0)Wheels:Position: (0, -0.8, 0)
第二帧:frame: 20Cab:Rotaition: (0, 0, -2.75)Wheels:Position: (0, -0.85, 0)
第三帧:frame: 30Cab:Rotaition: (0, 0, -3.5)Wheels:Position: (0, -0.88, 0)
第四帧:frame: 40Cab:Rotaition: (0, 0, -2.1)Wheels:Position: (0, -0.82, 0)
第五帧:frame: 60Cab:Rotaition: (0, 0, 0)Wheels:Position: (0, -0.8, 0)
- 为
Cab物体添加Wander.cs,然后取消Facing Right的勾选,并设置Moving Speed为5 - 将
Rigidbody2D组件的Body Type设置为Kinematic - 为
Cab物体添加Destroyer.cs,勾选Destroy On Awake,并设置Awake Destroy Delay为10
- 将
Cab物体拖拽至Assets\Prefabs\Environment文件夹下将其制作为Prefab,并删除场景中的Cab物体
  制作好出租车的动画,接下来我们开始制作巴士的动画。
巴士动画的制作步骤如下:
- 将
Assets\Sprites\Props下Bus图片切割得到的Bus拖拽到游戏场景中,接着设置SpriteRenderer组件的Sorting Layer为Background,并设置Order In Layer为5 - 将
Cab图片切割得到的Wheels拖拽到游戏场景中的Bus物体下成为其子物体,接着设置Wheels的Position为(-0.1, -1.67, 0),然后设置SpriteRenderer组件的Sorting Layer为Background,并设置Order In Layer为6 - 打开
Animation窗口,选中Bus物体,然后点击Create创建一个名为Bus.anim的动画文件,并将其保存在Assets\Animation\Environment文件夹下 - 将
Assets\Animation\Environment文件夹下的Bus.controller移动到Assets\Animator\Environment文件夹下 - 点击
Animation窗口的红点按钮,开始为Bus.anim添加关键帧,添加的关键帧信息如下:Bus.anim的关键帧:第一帧:frame: 0Cab:Rotaition: (0, 0, 0)Wheels:Position: (-0.1, -1.67, 0)
第二帧:frame: 20Cab:Rotaition: (0, 0, 1.58)Wheels:Position: (-0.1, -1.71, 0)
第三帧:frame: 30Cab:Rotaition: (0, 0, 2.5)Wheels:Position: (0, -1.75, 0)
第四帧:frame: 40Cab:Rotaition: (0, 0, 1.73)Wheels:Position: (0, -1.69, 0)
第五帧:frame: 60Cab:Rotaition: (0, 0, 0)Wheels:Position: (-0.1, -1.67, 0)
- 为
Bus物体添加Wander.cs,然后取消Facing Right的勾选,并设置Moving Speed为3.5 - 将
Rigidbody2D组件的Body Type设置为Kinematic - 为
Bus物体添加Destroyer.cs,勾选Destroy On Awake,并设置Awake Destroy Delay为14

- 将
Bus物体拖拽至Assets\Prefabs\Environment文件夹下将其制作为Prefab,并删除场景中的Bus物体
  制作好巴士的动画之后,接下来我们开始制作天鹅的动画。
天鹅动画的制作步骤如下:
- 在
Hierarchy窗口中创建一个名为Swan的Empty GameObject - 选中
Assets\Sprites\Props下swan_Sheet图片切割得到的所有图片,然后将它们都拖拽到Swan物体上,接着将Unity自动创建的动画文件命名为Swan.anim,并将其保存在Assets\Animation\Environment文件夹下 - 将
Assets\Animation\Environment文件夹下的Swan.controller移动到Assets\Animator\Environment文件夹下 - 设置
Swan物体的SpriteRenderer组件的Sprite为swan_Sheet图片切割得到的Swan_Sheet1_0,然后设置其Sorting Layer为Background,并设置Order In Layer为7 - 为
Swan物体添加Wander.cs,然后取消Facing Right的勾选,并设置Moving Speed为5.5 - 因为天鹅能往上飞,所以我们需要将
Swan物体的Rigidbody2D组件的Gravity Scale设置为-0.04 - 为
Swan物体添加Destroyer.cs,勾选Destroy On Awake,并设置Awake Destroy Delay为10

- 将
Swan物体拖拽至Assets\Prefabs\Environment文件夹下将其制作为Prefab,并删除场景中的Swan物体
生成不可交互物体
  制作好Cab、Bus和Swan的Prefab之后,接下来,我们开始制作能实例化这些Prefab的Generator。首先,我们在Hierarchy窗口的Generator物体下创建一个名为Non-interactiveObjectGenerators的Empty GameObject。接着,我们在Non-interactiveObjectGenerators物体下创建CabGenerator、BusGenerator和SwanGenerator三个Empty GameObject,并为它们添加Generator.cs组件。
各个Generator的设置如下:
CabGenerator:Position: (-22, -8.5, 0)Generate Delay: 3Generate Interval: 12Prefab Orientation: RightPrefabs:Element0:Assets\Prefabs\Environment文件夹下的Cab物体的Prefab
BusGenerator:Position: (-22, -7.65, 0)Generate Delay: 8Generate Interval: 14Prefab Orientation: RightPrefabs:Element0:Assets\Prefabs\Environment文件夹下的Bus物体的Prefab
SwanGenerator:Position: (-24, -3.2, 0)Generate Delay: 2Generate Interval: 10Prefab Orientation: RightPrefabs:Element0:Assets\Prefabs\Environment文件夹下的Swan物体的Prefab
  运行游戏,可以看到此时我们已经能产生从左到右运动的物体,接下来我们还需要产生能从右到左运动的物体。首先,我们将CabGenerator、BusGenerator和SwanGenerator分别拖拽至Assets\Prefabs\Generators下将它们制作为Prefab。接着,我们分别复制Non-interactiveObjectGenerators物体下已经成为Prefab的实例对象的CabGenerator、BusGenerator和SwanGenerator子物体。
各个复制得到的Generator的设置如下:
CabGenerator(1):Position: (22, -8.5, 0)Generate Delay: 15Generate Interval: 12Prefab Orientation: LeftPrefabs:Element0:Assets\Prefabs\Environment文件夹下的Cab物体的Prefab
BusGenerator(1):Position: (22, -7.65, 0)Generate Delay: 18Generate Interval: 14Prefab Orientation: LeftPrefabs:Element0:Assets\Prefabs\Environment文件夹下的Bus物体的Prefab
SwanGenerator(1):Position: (24, -0.1, 0)Generate Delay: 2Generate Interval: 10Prefab Orientation: LeftPrefabs:Element0:Assets\Prefabs\Environment文件夹下的Swan物体的Prefab
  再次运行游戏,可以看到此时我们已经能产生从右到左运动的物体。
后言
  至此,我们已经完成了随机生成不可交互物体的功能。最后,本篇文章所做的修改,可以在PotatoGloryTutorial这个仓库的essay14分支下看到,读者可以clone这个仓库到本地进行查看。