《土豆荣耀》重构笔记(十三)实现放置炸弹的功能
前言
  在上篇文章,我们已经实现了对怪物造成伤害的功能,但此时我们只有发射导弹
一种攻击方式。为了增加游戏的可玩性,我们将制作炸弹
,玩家可以通过放置炸弹来对范围内的怪物造成伤害
。在开始制作炸弹
之前,我们先梳理一下和炸弹
有关的需求。
和
炸弹
有关的需求:
炸弹
会对爆炸半径
内的怪物
和角色
造成一定的伤害
炸弹
会对爆炸半径
内的怪物
和角色
产生一个冲击力
炸弹
被释放后,会先燃烧一段时间引信
,然后再爆炸- 角色可以在原地释放
炸弹
、也可以通过火箭筒向前发射炸弹
炸弹
属于大威力道具,因此炸弹
的放置有冷却时间
限制,且炸弹
的数量是有限的
制作炸弹Prefab
  清楚了炸弹
的需求之后,我们先来制作炸弹
并实现炸弹
爆炸对怪物
和角色
造成伤害的功能。首先,我们将Assets\Sprites\Props
下的prop_bomb
拖拽到Hierarchy
窗口中,然后将其重命名为Bomb
。此时,可以看到场景里面出现了一个炸弹
,但尺寸比较大。这里,我们需要先将Assets\Sprites\Props
下的prop_bomb
的Pixel Per Unit
改为500
。
  接着,因为炸弹
能对角色造成伤害,为了在检测时提高效率,我们不能将Player
的Layer
设置为Default
,因为Layer
为Default
的物体很多,这会让我们增加很多不必要的判断。我们首先新建一个名为Player
的Layer
,然后在Layer Collision Matrix
中取消Player-Setting
项的勾选,不让Player
和Setting
这两个Layer
的物体产生任何物理交互。最后,我们将物体Player
的Layer
设置为Player
,并将其修改Apply
至Player
的Prefab上。
  接着,我们在Assets\Scripts\Weapons
新建一个名为Bomb
的C#脚本,然后编辑Bomb.cs
如下:
1 |
|
代码说明:
m_LayerMask
: 为了让大家能理解LayerMask
的本质,我这里没有使用LayerMask.GetMask
这个静态方法来获取Layer Mask
,而是直接使用了位运算
StartCoroutine
:用于开始执行一个Coroutines(协程)
,Unity中的协程是基于C#提供的IEnumerator(迭代器)
实现的。Unity的协程
功能非常强大,使用起来也比较简单。我们只需要先定义一个返回类型为IEnumerator的方法
,然后在这个方法里面使用yield语句
来设置协程等待的条件,并使用StartCoroutine
来执行该方法。那么当程序执行到yield语句
这里的时候,就会停止执行后面的代码,然后每帧检查是否满足条件
,一旦满足条件就继续往下执行。Physics2D.OverlapCircleAll
:Unity提供的api,用于获取在某个圆形范围内的所有Collider2D
。
  编辑完毕之后,我们将Bomb.cs
添加到Hierarchy
窗口的Bomb
物体上,可以看到Unity自动帮我们在Bomb
物体上添加了AudioSource
组件。为了让炸弹
具有物理属性,能和场景里其他物体发生物理碰撞,我们还需要为Bomb
物体添加Rigidbody2D
和Circle Collider2D
组件。然后,我们对每个组件进行以下的设置:
Bomb
物体的组件设置:
Sprite Renderer
:Sorting Layer
: WeaponsOrder In Layer
: 0
Bomb
:DamageAmount
: 50BombRadius
: 10BombForce
: 800BoomClip
:Assets\Audio\FX
下的bigboom
FuseTime
: 1.5fFuseClip
:Assets\Audio\FX
下的bombfuse
Circle Collider2D
:Is Trigger
: falseOffset
: (0, 0)Radius
: 0.5
Rigidbody2D
Gravity Scale
: 3.1
  设置完毕之后,保存修改,然后将Bomb
物体从Hierarchy
窗口拖拽至Assets\Prefabs\Weapons
下将其做成Pfefab。接着,我们运行游戏,可以听到炸弹
燃烧引信和爆炸的音效,也能看到角色和怪物被炸弹炸飞并受到伤害的效果。但炸弹
在燃烧引信
和爆炸
的时候,没有任何的特效,无法让玩家直观地意识到炸弹在燃烧引信
和炸弹爆炸了
。因此,我们还需要为炸弹
添加引信燃烧特效
和爆炸特效
。
为炸弹添加爆炸特效
  接下来,我们首先为炸弹
添加爆炸
特效。首先,我们将Assets\Sprites\FX
下的Circle
拖拽到Hierarchy
窗口中,并将Circle
物体重命名为BombExplosion
。接着,我们将Assets\Scripts\Utility
下的Destroyer.cs
添加到BombExplosion
物体上,并修改Destroyer.cs
如下:
1 |
|
  接着,我们设置BombExplosion
物体的组件如下:
BombExplosion
物体的组件设置:
Sprite Renderer
:Sorting Layer
: WeaponsOrder In Layer
: 3
Destroyer
:Destroy On Awake
: trueAwake Destroy Delay
: 0.1
  修改完成之后,我们将BombExplosion
物体拖拽至Assets\Prefabs\Weapons
文件夹下将其制作为Prefab。然后我们删除场景中的BombExplosion
物体,选中Bomb
的Prefab,将其Bomb.cs
下的Bomb Explosion
属性设置为BombExplosion
的Prefab。最后保存修改,运行游戏,可以看到炸弹爆炸时产生了爆炸特效。
为炸弹添加引信燃烧特效
  为炸弹
添加完爆炸
特效之后,我们为炸弹
添加引信燃烧
特效。首先,我们在Bomb
物体下创建一个名为Sparks
的Empty Gameobject
,然后我们为其添加Particle System
组件。
Sparks
物体的Particle System
组件设置:
- Main Module:
Start Lifetime
: 0.5Start Size(Random Between Two Constants)
: (0.2, 1)Start Rotation(Random Between Two Constants)
: (0, 360)Gravity Modefier
: 1Simulation Space
: WorldScaling Mode
: ShapeMax Particles
: 100
- Emission:
Rate Over Time
: 40
- Shape:
Angle
: 36Radius
: 0.01Arc
: 0.01Randomize Direction
: 1
- Size over Lifetime:
Size(Random Between Two Constants)
: (0.4, 0.6)
- Rotation over Lifetime:
Angular Velocity(Random Between Two Constants)
: (0, 180)
- Texture Sheet Animation
Tiles
: (2, 2)
- Render
Material
:Assets\Materials
下的ExplosionParticle
Sorting Layer
: WeaponsOrder In Layer
: 4
  修改完成之后,我们还需要调整Sparks
的Transform
组件。
Sparks
物体的Transform
组件设置:
Position
: (0.47, 0.53, 0)Rotation
: (0, 90, 0)
  最后,我们将Bomb
物体上的修改Apply
至其Prefab上,然后运行游戏,可以看到炸弹
已经有了引信燃烧
特效了。
释放炸弹
  为炸弹
添加好引信燃烧
和炸弹爆炸
特效之后,我们需要让角色能够释放炸弹。首先,我们删除场景中的Bomb
物体。接着,我们修改PlayerAttack.cs
如下:
1 |
|
  修改完成之后,我们将BombPrefab
设置为Bomb
的Prefab,运行游戏,此时我们可以通过单击鼠标右键
来在原地释放炸弹
以及通过单击鼠标滚轮
来向前抛射炸弹
。最后,我们将Player
的修改Apply
至其Prefab上,保存场景的修改。
后言
  至此,我们已完成实现放置炸弹的功能的所有工作。本篇文章涉及到的一些数值参数,大家可以根据自己的喜好进行修改。最后,本篇文章所做的修改,可以在PotatoGloryTutorial这个仓库的essay11
分支下看到,读者可以clone这个仓库到本地进行查看。