前回はPlayerの攻撃を作って、敵に当てるところまで完成しています。今回は敵のHPが0になったタイミングで爆発を発生させて、敵を消滅させるところまで。
では早速作っていきましょう。
これまで使ってきた爆発のエフェクトは、若干地味なので、派手なアクションを使いたいと思います。アセットストアにアクセスして取得します。
①今回選んだのは「True Explosions!」。ボリュームも多くないようなので、全てインポートしておきましょう。(一部だけ取得したら、エラーが発生してしましました。原因を追及するよりも全部取得したほうが効率がいいです)

②取得したアイテムから、[System] => [Prefabs] と進んでいただき、「Explosion2D」というプレハブを使います。
このまま使うと、大きすぎたり、また速すぎたりするので、若干修正しておきます。「Explosion2D」をダブルクリックして、編集モードに入ります。

この「Explosion2D」は3つの子要素で形成されているようです。まずはすべての子要素の「Renderer」を指定します。
ParticleSystemの 「Renderer」の指定方法は、前回学習しましたね。
③子要素3つを選択した状態で、Instagramの「ParticleSystem」コンポーネントを展開します。この「Renderer」というくくりのなかの「Sorting Layer ID」という値を「Player」に指定します。
これでは 「StationA」より手前に見えてくるはずです。

続いて子要素、1つずつ、パラメータを指定していきます。
④「ShockWave」 は衝撃波です。爆発の前に走る波ですね。
初期設定では、大きすぎるので「StartSize」を5に変更します。さらに動きが早すぎるので「Sumiration Speed」を0.8 に変更します。

⑤つづいて子要素の「FireBall」の値を変更します。これは爆発時に発生する火の玉、つまり爆発本体です。
初期設定では、やはり大きすぎるので「StartSize」を変更します。値を2つ指定できるようですが、左と右の間の乱数という意味の様です。今回は左に1を、右に2を入れて、1から2の間の乱数と指定します。
動きはやはり早すぎるので「Sumiration Speed」を0.5 に変更します。
⑥「BaseSmoke」は爆発後の煙です。これは「FireBall」と同じ値にしましょう。

これで素材の準備はOKです。ではプログラムを改造していきます。
前回作成したスクリプトファイル「EnemyStationAManager.cs」を立ち上げてください。
先に爆発のコルーチン型関数を作っていきます。
事前に 変数:explosion という名前で爆発プレハブ を指定しておきます。
StationA_Bomb() という名前のコルーチン型関数をでは以下の14個の処理を記述していきます。
❶前回作成した、動きを管理する Bool型変数:IsMove を false に指定します。
これで通常の動きを止めます。後で通常の動きを管理する関数「StationA_Move()」を一部修正します。
❷新たな動きは止まりますが、現在速度を持ってしまっているので、それを止める必要があります。そこで、今持っているvelocity を 0 にします。
❸StationA上のいろいろな場所で小爆発を発生させたいと思います。
foh文を使って、小爆発を生成するプログラムを20回繰り返します。
❹爆発の発生場所のx座標を決めています。StationAのポジションから左右に4の範囲から乱数で取得します。
❺は❹と同じで、y座標を指定しています。StationAは縦長なので、上下に8の範囲を指定しています。
❻は連鎖的に爆発が発生する演出です。繰り返し処理の中に0.1秒から0.3秒の乱数をとって、不規則な連鎖を表現します。
❼ここで爆発プレハブを生成します。❹と❺で指定した場所を使っています。
❽20回の繰り返しが終わったら、最後の大爆発を生成します。
今までのプレハブと違って、大きく、長く爆発を表現したいので、いったん生成したプレハブをゲームオブジェクトとして変数化しておきましょう。
❾生成のポジションはStationAの場所をします。
➓爆発の大きさ、速さを指定するには、プレハブの「ParticleSystem」の各パラメータを指定する必要があります。このコードでは、子要素の「FireBall」を探してきて、「ParticleSystem」コンポーネントを取得、それをvar型(推論型)の変数に代入します。
var型は推論型なので、同じコード内から型を推論できなければならないですね。今回は「ParticleSystem」型と推論できるので、使うことができました。
⓫ParticleSystem」の startSize を50に指定して、大爆発を作ります。
⓬同様に playbackSpeed を0.2f にすることで、爆発をゆっくり処理、つまり長く存続できるように指定します。
⓭StationAは爆発直後に消えると不自然なので、2秒待ちます。
⓮最後はDestroy関数で削除です。
[SerializeField] GameObject explosion; //爆発のプレハブ
IEnumerator StationA_Bomb()
{
IsMove = false; //❶通常の動きを止める
sARb2d.velocity = transform.up * 0; //❷速度を0にする
for (int i = 0; i < 20; i++) //❸小さな爆発を20回繰り返す
{
float x = transform.position.x + Random.Range(-4.0f, 4.0f); //❹爆発位置(x)
float y = transform.position.y + Random.Range(-8.0f, 8.0f); //❺爆発位置(y)
yield return new WaitForSeconds(Random.Range(0.1f, 0.3f)); //❻爆発間隔
Instantiate(explosion, new Vector3(x, y, 1), Quaternion.identity);//❼爆発生成
}
//最後の大爆発の処理
GameObject bomb = Instantiate(explosion); //❽大爆発を生成し変数にセット
bomb.transform.position = transform.position; //❾ポジション指定
//➓fireBall の子要素"FireBall"から「ParticleSystem」を取得し変数にセット
var fireBall = bomb.transform.Find("FireBall").GetComponent<ParticleSystem>();
fireBall.startSize = 50; //⓫大きさを指定
fireBall.playbackSpeed = 0.2f; //⓬スピードを指定
yield return new WaitForSeconds(2f); //⓭2秒待つ
Destroy(gameObject); //⓮削除
}
これで爆発演出ができました。
あとは既存のプログラムを修正して、このコルーチンを発動させましょう。
侵入判定 OnTriggerEnter2D() 関数の中で、"PlayerMissile"が侵入してきたら、hpを減らすというプログラムを前回作成しました。その中に追記します。
⓯もしhpが0になったら、StartCoroutine()関数で、上で作成した関数 StationA_Bomb() を発動しています。
⓰は修正です。前回やればよかったのですが、 while (true) を while (IsMove) に修正します。これで、爆発が始まったら動きがストップします。
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "PlayerMissile")
{
hp--; //記述済み
Debug.Log("ボス:"+hp); //記述済み
if (hp == 0) //⓯もし hp が 0 になったら
{
StartCoroutine(StationA_Bomb()); //コルーチン StationA_Bomb() 発動
}
}
}
IEnumerator StationA_Move()
{
//記述済み
transform.position = new Vector3(Random.Range(-15f, 15f), 12f, 0);
sARb2d.velocity = new Vector2(0, -1f); //記述済み
yield return new WaitForSeconds(3); //