いのいち勉強日記

Sakana AIでResearch Engineerをしています。京大薬学研究科でPhDをとりました。Kaggle Grandmasterです。

【Unity】シューティングゲームを作ってみよう!《Day 3》OnTriggerEnter2Dの実装、Textの更新

3日目は「EnemyとBulletの衝突判定を認識しScoreが増える」を実装します。

 

 

ゲーム作り3日目

 

OnTriggerEnter2DでBulletとEnemyの衝突処理

 

まずはBulletとEnemyが衝突した時にお互いが消えるようにしました。

Kinematic状態なのでこの二つは衝突しません!!!

なので、

OnCollisionEnter2Dではなく

OnTriggerEnter2Dを使います!!

collisionの時とtriggerのときで引数やTagの取り方が違ったりするので、

初心者には最初ややこしいですね…

 

OnTriggerEnter2Dのときは

引数がCollider2D, Tagは「引数.tag」で所得します。

 

OnCollisionEnter2Dのtagは「引数.gameObject.tag」で取るそうです!

よく考えたらColliderとCollisionなので納得できますが、

はじめはややこしいですよね!!!

 

Trigger関数を呼び出すのは

EnemyでもBulletでもどちらでも良いのですが、

あとでEnemyはライフを減らす処理も実装したいので、

Enemyの方でOnTriggerEnter2Dを書くことにしました!

まずはEnemyの「Is Trigger」にチェックを入れ、

コードはこんな感じで書きました。

 

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

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

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

 

 どのオブジェクトがTriggerをオンにしたかを認識するために

Bulletに「Bullet_Red」のタグをつけておきました。

TagはInspectorの上の方で作れました!

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

 

 

画面の外に出た時にGameObjectをDestroy!

 

次に、BulletとEnemyはお互いに当たらなかった場合

画面の外に出て永遠に見えないところで進み続けます。

これはきっと容量とかの無駄なので

画面の外に「Wall」を作ってそれに当たったら

BulletもEnemyも消えるようにしました。

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

オレンジっぽい色の長方形がWallです!

BulletやEnemyがインスタンス化されるところには

被らないように配置しました!

 

コードは先ほどのOnTriggerEnter2Dとほぼ同じで、

Wallに「Wall」のタグ付けをして、

EnemyとBulletの両方でWallに当たったら消えるようにしました!

f:id:sys-bio:20180328015102g:plain

左のHierarchyを見るとEnemyも消えているのがわかるかと思います!

 

 

Enemyを撃ち落とした時にスコアを更新

 

最後にEnemyとBulletが当たった時にスコアが入るようにしました。

まずは左下にスコアを表示するImageと、その下にTextを配置しました。

Textの値を変更して点数を表示する関数はGameManagerで行います!

これはあとでコインとか別の得点する方法を考えた時に

GameManagerに関数を作って呼び出す形にした方が

楽に実装できると思ったからです!

 

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

public void UpdateScore (int score) {
        nowScore += score;
        textScore.GetComponent<Text>().text = nowScore + " P";
    }

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

TextScoreに先ほど配置したTextを関連づけて

TextをGetComponentで取得して、

この関数が呼び出されるたびに

引数の数値だけスコアが増える関数です。

 

そして実際にこの関数を呼び出すのは

先ほどEnemyのOnTriggerEnter2Dの中です!

GameManagerから関数を呼び出すので

Start関数の中で取得しています!

 

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

void Start () {
        rbody = gameObject.GetComponent<Rigidbody2D> ();
        gameManager = GameObject.Find ("GameManager");
    }

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

 

Enemyを動かすために書いたrbodyとは違って、

Findメソッドで、画面中に存在する「GameManager」を取得しています!

 

 

そして、BulletとEnemyが衝突した時に点数が入るようにしました!

 

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

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);
        }
    }

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

 

最終的にEnemyのOnTriggerEnter2Dの中身はこんな感じになっています!

これで今回の目標達成です!

f:id:sys-bio:20180328020535g:plain

 

 

まとめ

 

衝突判定はすごく実装が簡単だなと思います!

少しややこしいのが、

OnCollisionEnter2DとOnTriggerEnter2Dの使い分けだと思います。

でも初心者なんで正直どっちがいいとかまだ判断できないので

とりあえずうまくいけばいいかな!って思ってます。

でもこういう使い分けはどうやって学んでいくのだろう…

と思うわけですが、もしこんな使い分けしてるよっていうのがあれば

誰か教えて欲しいです。。。

 

次回は、Enemyが自分の領域に当たったり

大砲に当たったらライフを減らすのを実装していきます!

 

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