Unityで作る「シューティングゲーム」Vol.19

前回は「中ボス」の外観と中ボスのタレットを作成しました。
今回はまずはタレットの動きを管理するプログラムの作成です。
では早速作っていきます。

1,中ボスタレットのプログラム

まずタレットの動きの要件ですが

  1. 通常は中ボスの上で回転しながら、不定期でミサイルを発射する
  2. HPを持っていて、特定回数ダメージを受ければ破壊される

この動きを実現するために、プログラミングを作成していきます。
前回最後に作成したスクリプトファイル、[EnemyStationATurret] を立ち上げて以下のコードを記述してください。

❶変数には要件を実現するために必要な「HP」「弾を発射する間隔」それと「弾の速さ」を指定します。
またゲームオブジェクトとして「発射する弾」と「HPが0になったとき爆発するエフェクト」この2つを指定します。

❷弾を発射する関数ですが、発射する間に時間を持つため、「コルーチン」を使用します。
while() 関数で「発射」と「待機時間」を繰り返します。
「待機時間」は「Random.Range」を使って0.5秒から4秒の乱数秒に指定します。
弾は「Instantiate()関数」を使って生成、いったんオブジェクト化します。
オブジェクト化した弾に「AddForce()関数」で直接速度を与えています。

❸イベント関数「OnTriggerEnter2D()」でプレイヤーの弾との当たり判定を行っています。
プレイヤーの弾が当たるたびにHPを 1 ずつ減らし、HPが 0 になったら爆発のエフェクトを生成し、1,5秒後にエフェクトを削除します。
さらに自分自身を削除しています。

❹Start関数内で、❷で宣言したコルーチン型の関数を起動させています。
コルーチンを起動させるには、StartCoroutine(Shot()) ですね。

❺Update関数内では、 transform.Rotate()関数 を使ってタレットをぐるぐる回しています。

//❶変数の宣言
int hp;                                   //ヒットポイント
float shot_speed;                         //弾の速さ
float shotDelay;                          //弾を撃つ間隔
[SerializeField] GameObject EnemyBullet;  //EnemyBulletを格納
[SerializeField] GameObject explosion;    //爆発エフェクト

IEnumerator Shot()      //❷弾を生成するコルーチン型関数
{
    yield return new WaitForSeconds(1);             //仮の待ち時間 
    while (true)                                    //内部の同じ動きを繰り返す 
    {
        shotDelay = Random.Range(0.5f, 3f);         //発射の間隔を0.5~4秒の乱数 
        yield return new WaitForSeconds(shotDelay); //指定した間隔待って次の処理へ 
        GameObject bullet = Instantiate(EnemyBullet, transform.position, transform.rotation);//弾生成
        bullet.GetComponent<Rigidbody2D>().AddForce(bullet.transform.up * shot_speed); //弾に速度付与
    }
}

void OnTriggerEnter2D(Collider2D collision)        //❸ダメージ判定のイベント関数
{
    if (collision.gameObject.tag == "Projectile" ) //Player の攻撃に当たったら 
    {
        Destroy(collision.gameObject);             //弾の削除
        hp--;                                      //hp を1ずつ減らす 
        if (hp == 0)                               //HPが0になったら 
        {  
            GameObject effect=Instantiate(explosion, transform.position, transform.rotation);//爆発生成
            Destroy(effect, 1.5f);                //爆発エフェクトの削除 
            Destroy(gameObject);                   //Enemyの削除 
        }
    }
}

void Start()
{
    hp = 50;                                       //hp の初期値を50に指定 
    shot_speed = 800;                              //ショットスピードを800に指定 
    StartCoroutine(Shot());                        //❹ショットコルーチンを発動
}

void Update()
{ 
    transform.Rotate(new Vector3(0, 0, 0.1f));     //❺ずっと回転
}

Unityエディタで「TurretLargeRight」のインスペクターに移ると、スクリプトファイルに2つの変数(オブジェクト)を入れる枠ができています。

①下の図のようにそれぞれ EnemyBUlletPrefab、 Explosion1 を指定しておきます。

Unityで作る「シューティングゲーム」Vol.19

Explosion1プレハブですが、うまく表示されないという不具合があるようです。
Sorting Layer がデフォルトのままでは、背景画像の後ろに隠れてしまうようです。
以下のように修正しておきます。

②「Explosion1プレハブ」を選択、Inspector から 「Particle System」コンポーネントの下側にある「SortingLayerID」に、すでに作成している「Turret」を指定します。
これで爆発演出が一番上に表示されるはず。

Unityで作る「シューティングゲーム」Vol.19

ではこれで動かしてみましょう。
下の図のように、タレットからミサイルが発射されているのがわかると思います。
(ちょっとわかりにくいかもしれません)

Unityで作る「シューティングゲーム」Vol.19

さらにゲームを続けると、プレイヤーの撃った弾、敵が撃った弾が中ボスに当たってしまい、タレットを攻撃することができないようです。
そこで次のようなルールを設けます。

  • Playerの弾は中ボスに当たらない
  • Enemyの弾も中ボスに当たらない

ではどうやってこれを実現させればよいでしょうか?
現状、Playerの弾には次のようなコードが記述されています。

void OnTriggerEnter2D(Collider2D col)
{
    if (col.gameObject.tag != "Projectile") 
    {
         Instantiate(hit_effect, transform.position, Quaternion.identity);
         Destroy(gameObject);
    }
}

当たった対象のゲームオブジェクトが持っているタグが、”Projectile” でなければ自分自身を削除する、というプログラミングです。
ここに「または」で他のタグを追加していってもいいのですが、今回は別の方法を学習します。
まず、登場人物に「Layer」を追加します。

③どのオブジェクトでもいいので、まずは「Layer」を選択し、一番下に表示される「Add Layers」をクリックします。

④今回登場する3種類のオブジェクト用に、以下の3つのLayerを作成します。
「Player」「Enemy」「EnemyStation」

Unityで作る「シューティングゲーム」Vol.19

⑤まずは「EnemyStation」を選択し、Inspectorの「Layer」に上で作成した「EnemyStation」を指定します。
英語で子要素にもそのLayerを加えるか聞いてきます。
今回は子要素にはつけないので「No,this objekt only」を選択します。

Unityで作る「シューティングゲーム」Vol.19

⑥同様にプレハブの「PlayerBulletPrefab」を選択し、Layer「Player」を追加

⑦プレハブの「EnemyBulletPrefab」また、「Enemy2Vullet」を選択し、Layer「Enemy」を追加

Unityで作る「シューティングゲーム」Vol.19

これでレイヤーの準備ができました。
続いてそれぞれのLayerが他のLayerに影響を与えるかどうかを指定します。

⑧上部メニューの「Edit」から「Project Settings」を選択。
「Physics2D」の下部、「Layer Collision Matrix」を選択。
「EnemyStation」と「Player」「Enemy」が交わる部分のチェックを外します。

Unityで作る「シューティングゲーム」Vol.19

ではこの状態で起動させてみましょう。
うまくいったら、スクリプトファイル [EnemyStationATurret] を残りの2つのタレット「Turret Large Left」「Turret Large Center」にも追加し、オブジェクト変数に各プレハブをセットしておきましょう。

だいぶ難しいゲームができてきました。みなさん、ついてきているかな??

今回はここまで、次回は中ボスを動かしてみましょう。

教室では実際に通って頂いての授業の他、ちょっとしたお困りごとに対するオンライン授業やオンラインサポートも行っております。
お困りごとのある方、ご興味がある方は、ぜひお問い合わせください。
お問い合わせは こちら から。
体験授業のお申込みは こちら から。

無料体験授業 いつでも受け付けています!

体験授業を受ける子供

スクラッチ、Unityでちょっとしたゲームを作ってみる

HTMLやCSSでWebサイト作成体験

初めてパソコンやタブレットに触れてみる

エクセルやワード、パワーポイントの学習をちょっと体験

まずは1時間程度の無料体験授業を受けて、教室の雰囲気や講師の人柄に触れて頂き、ご自身、お子様に合うのかどうかご確認ください!