《土豆荣耀》重构笔记(十六)随机生成不可交互物体
前言
  在前面的文章中,我们提到,为了不让游戏背景那么一成不变,显得更有动感一点,我们通常需要加入一些不能与游戏内的元素发生交互的背景动画
。但有一些作为背景动画的物体并不是在进行重复运动的
,我们不能简单地为制作循环播放的动画,而是要使用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这个仓库到本地进行查看。