いのいち勉強日記

Turingで自動運転の開発をしています。京大でPhDをとりました。Kaggle Grandmasterです。

【Unity】シューティングゲームを作ってみよう!《Day 4》ライフが減る処理の実装

4日目は「Enemyが自分の陣地や大砲にに当たったらライフを減らす」を実装します。

3日目で使ったOnTriggerEnter2DとTagを駆使しました!

 

 

ゲーム作り4日目

 

Enemyが当たるとライフが減るオブジェクトにTagをつける

まずは画面にライフの残り数を表すスターを貼り付けました。

そして右から順に1、2、3としています。

 

さらに、Enemyが自分の領域に当たったことを認識するために

「PointWall」というピンク色の壁を用意しました。

f:id:sys-bio:20180329053559p:plain

 

そして、これに「PointWall」というtagをつけて認識できるようにしました。

 

そして、大砲にRigidbody2DとColliderをつけて

「Cannon」というTagをつけて認識できるようにしました。

 

PointWallに当たったらライフが1なくなる

Cannonに当たったらライフが全てなくなる

この2つを実装できるようにTagをわけてつけました。

 

ライフを減らす処理についてですが、

EnemyのスクリプトにPointWallかCannonとの接触判定を実装し、

ライフを減らす関数はゲームの進行なのでGameManagerで実装します。

 

ライフを減らす関数の実装

 

ライフを減らす関数には

PointWallかCannonのどちらに当たったかが

わかるように引数としてint型の値を取るようにしました。

これが1の時、PointWallに当たってライフが1減る。

これが3の時、Cannonに当たってライフが全て減る。

というのをコードにしました。

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

    public void LifeDelete (int lifeRate) {
        if (lifeRate == 1) {//壁に当たった
            switch (lifeRemain) {
            case 3:
                lifeRemain = 2;
                lifeStar3.SetActive (false);
                break;
            case 2:
                lifeRemain = 1;
                lifeStar2.SetActive (false);
                break;
            case 1:
                lifeRemain = 0;
                lifeStar1.SetActive (false);
                ShowGameOver ();
                break;
            }
        }

        if (lifeRate == 3) {//大砲に当たった

            lifeRemain = 0;
            lifeStar3.SetActive (false);
            lifeStar2.SetActive (false);
            lifeStar1.SetActive (false);
            ShowGameOver ();
        }
    }

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 

コードをもう少し詳しく説明します!

 

引数の「lifeRate」でEnemyが何に当たったのかを判断しています。

 

そして「lifeRemain」はint型で残りのライフの数を入れています。

はじめは3で、PointWallに当たるごとに1づつ減らして

現在のライフの状況を認識しています。

 

「lifeStar1, 2, 3」はライフの星型の画像をGameObjectとして関連づけています。

 

GameObjectの非表示の方法は

GameObject.SetActive (false)

を使いました!

 

そしてライフが全部なくなった時に

ゲームオーバーを表示するための

ShowGameOverの関数を入れました!

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

      void ShowGameOver () {
        textGameOver.SetActive (true);
        buttonRed.interactable = false;
    }

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 

新しく画面に大きな「GAME OVER」というTextを入れて

GameObjectとして関連づけておきます。

そして、名前の横のチェックボタンを外し初期設定で非表示にしておきます。

f:id:sys-bio:20180329055023p:plain

ShowGameOver関数が呼ばれたら、表示されるようにしました。

 

また、ゲームオーバーのときは発射ボタンが押せないようにしました。

 

これは赤の発射ボタン「buttonRed」をButton型で取得し、

public Button buttonRed;)

interactableというのを使いました!

 

これをFalseにすることで、

ボタンは消えないけど半透明になって押せなくなる

というのを実現できます!!!

そちらの方が見栄えがいいのでSetActiveではなくinteractableで実装しました!

 

OnTriggerEnter2Dで当たりを認識

 

最後にEnemyのOnTriggerEnter2Dにtagで場合分けして

処理を書いたら完成です!

Enemy中のOnTrigger関数の中身が増えてきました!!

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

      void OnTriggerEnter2D (Collider2D col) {
        if (col.tag == "Bullet_Red") {
            Destroy (this.gameObject);
            Destroy (col.gameObject);

            gameManager.GetComponent<GameManager>().UpdateScore (bulletHitPoint);
        }

        if (col.tag == "Wall") {
            Destroy (this.gameObject);
        }

        if (col.tag == "PointWall") {
            gameManager.GetComponent<GameManager> ().LifeDelete (1);
        }

        if (col.tag == "Cannon") {
            gameManager.GetComponent<GameManager> ().LifeDelete (3);
        }
    }

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 

しかし、よく見たら、3日目で実装した

"Wall"との接触判定はいらないことに気がついてしまいました…

 

でもせっかく書いたので

Wallはオブジェクトを消す

PointWallはライフを減らす

という使い分けとして残しておきます!

 

 

まとめ

 

今回はライフを減らすコードを書きました!

ライフの減り方を2種類にしましたが、

実装自体はすごく簡単に実装できたと思います!

 

今回作って見て気づいたのですが、

このままではゲームオーバーになっても

Enemyは上からどんどん出てきてしまいます。

 

それは不自然だ!

 

ということで、次回は、ゲームオーバーになったら

上からEnemyが出てくるのをやめる!っていうのを

「列挙型」を使って実装してみようかなと思います!

 

読んで頂きありがとうございました!!