《土豆荣耀》重构笔记(十三)实现放置炸弹的功能
前言
  在上篇文章,我们已经实现了对怪物造成伤害的功能,但此时我们只有发射导弹一种攻击方式。为了增加游戏的可玩性,我们将制作炸弹,玩家可以通过放置炸弹来对范围内的怪物造成伤害。在开始制作炸弹之前,我们先梳理一下和炸弹有关的需求。
和
炸弹有关的需求:
炸弹会对爆炸半径内的怪物和角色造成一定的伤害炸弹会对爆炸半径内的怪物和角色产生一个冲击力炸弹被释放后,会先燃烧一段时间引信,然后再爆炸- 角色可以在原地释放
炸弹、也可以通过火箭筒向前发射炸弹 炸弹属于大威力道具,因此炸弹的放置有冷却时间限制,且炸弹的数量是有限的
制作炸弹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下的bigboomFuseTime: 1.5fFuseClip:Assets\Audio\FX下的bombfuse
Circle Collider2D:Is Trigger: falseOffset: (0, 0)Radius: 0.5
Rigidbody2DGravity 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下的ExplosionParticleSorting 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这个仓库到本地进行查看。