プレイヤーが弾を撃ち敵に当たる処理を作成してみる[Unity2D]

Unity

シューティングゲームで必須の処理

現在シューティングゲームを作っている最中です。
シューティングゲームを作ろうとすると、ほぼ実装が必須な
処理の一つとして、プレイヤーのゲームオブジェクトが
弾を発射するというのがありますよね。

初心者に毛が生えた程度のゲーム開発者である私にとって
この弾を撃つというのは取り掛かる前のイメージでは結構簡単な処理だろ!
って思っていました。

しかし、いざ実際に実装しようとしてみると「えっと…どうすればいいの?」
ってなっちゃって具体的な実装が思いつきませんでした。

ただやってみるとUnityの何の機能を使えばいいのかが
分かっていればそんなに難しくはありませんでした。

なので今回はプレイヤーが弾を撃つ処理の作り方の一例を記載していこうと思います。

処理概要

まずは処理の全体像をイメージするため
どんな処理が必要なのか?を切り分けていきましょう。

大きく二つに分けます。
・ゲーム上のオブジェクトは何が必要なのか?
・C#プログラム上の処理で何が必要なのか?

1つ目はゲーム上のオブジェクトは何が必要なのか?についてです。
まず登場人物としてはプレイヤー、弾、敵の3人ですね。
で、この登場人物それぞれに対し以下が必要になってきます。
・ゲームオブジェクト(Unity上の変数)
・スプライト(登場人物の画像ファイル)
但し、スプライトもゲームオブジェクトの一種と考えていいと思うので
登場人物の画像ファイルがあればとりあえずそれでよいかと思います。

2つ目はC#プログラム上の処理で何が必要なのか?についてです。
大きく3つの処理に分かれます。

  1. プレイヤーの特定の位置から弾が生成される。
  2. 1.で生成された弾が一定の方向に対し直線で移動する
  3. 弾の移動先に敵がいた場合(敵に弾が命中した場合)敵がダメージを受ける

大まかな処理としては上記のようになります。

処理の詳細について

ではそれぞれについて詳細を記載していきます。

まずはシーン上にプレイヤー、弾、敵を配置しましょう。
まず弾についてですがプレイヤーが発射する瞬間に現れる(生成される)ので
prefab化しておきます。

次にプレイヤーと敵についてですが
今回は以下のようにy座標上に一直線になるように配置しました。

プレイヤーの位置(x ,y ,z) = (0, -7, 0)
敵の位置(x ,y ,z) = (0, 7, 0)
に設定してあります。

これで前提となる登場人物は全てUnity上に読み込んだので
あとはC#Scriptで処理を追加していきます。

まずはプレイヤー用のC#Scriptについてです。
ここではplayer.csという名前のC#Scriptを作成します。

player.cs内の処理内容ですが
何かのキーを押したら弾が発射するようにします。
どのキーでもいいのですがここでは左クリックにします。

こちらを実装したサンプルコードが以下になります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public GameObject bullet;
    Vector3 createPosition;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            createPosition = transform.position;
            createPosition.y += 1.0f; // プレイヤーのy座標 + 1の位置に弾を生成する

            Instantiate(bullet, createPosition, Quaternion.identity);
        }
    }
}

Instantiate がゲームオブジェクトを生成する関数です。

完成したplayer.csをプレイヤーのゲームオブジェクトにアタッチします。
そして弾のprefabをplayer.csの弾のゲームオブジェクトに設定します。
また弾のprefabには以下で説明するRigid Body 2DとBox Collider 2Dもアタッチします。
そしてRigidbody 2DのBody TypeはKinematicを選択しておきます。

この状態で一旦ゲームを実行してみましょうか。

左クリックを押すと弾が生成されますが、どこにも移動してくれません。
なので次に弾を移動させるようにプログラミングします。

では弾のC#Scriptについてです。
今回弾は生成されたらその瞬間から無我夢中で直線を移動するようにします。
単純のためy座標上を直線で移動するようにしましょう。
Bullet.csという名前でC#Scriptを作成しました。

こちらのサンプルコードは以下になります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        transform.Translate(Vector3.up * Time.deltaTime);
    }
}

Translateでゲームオブジェクトを移動させています。
Vector3.upで正のy座標に移動させます。
Time.deltaTimeはクライアントPCの性能の差を打ち消すために必要だと考えればいいかと思います。

player.cs同様に完成したbullet.csを
弾のゲームオブジェクトにアタッチします。

そして再度ゲームを実行してみます。

弾は生成した瞬間からy座標上を移動してくれました。
しかし敵に当たっても何も起きません…

そこで最後の処理を追加しましょう。
敵に弾が命中したら敵にダメージを与えます。

敵と弾が当たったという当り判定には基本的にUnityの
以下の機能が必要になります。
・Rigid Body 2D
・XXX Collider 2D
XXXの部分はCircleやBoxなどが入ります。
Colliderを日本語に訳すと衝突装置などの意味になります。

つまりCollider 2Dが当たり判定を行っているメインの機能なのですが
Unityの物理エンジンに従って当り判定を行っているため
ゲームオブジェクトを物理制御する機能であるRigid Body 2Dが
どうしても必要になってきます。
ということで当り判定を行いたい場合は
・Rigid Body 2D
・XXX Collider 2D
はセットで覚えるようにしましょう。

ではまず当り判定を行うため
弾と敵にRigid Body 2DとCollider 2Dをアタッチしましょう。
今回Colliderについては敵はCircle Collider 2Dをアタッチします。
弾はBox Collider 2Dをアタッチします。

これで当り判定が出来るようになりました。

次に敵と弾が当たった瞬間に処理が呼び出されるようにしたいですよね。
これは既にUnity上で決まった関数が存在しています。
それがOnTriggerEnter2Dです。(onCollisionEnter2Dもありますが今回はTriggerを使います。)
OnTriggerEnter2Dの実行時にはCollider2Dの引数が渡されます。
こちらは相手の衝突情報です。
この引数の情報から処理を記載していきます。

例えば衝突相手のタグ名が「Enemy」だった場合、
衝突相手にダメージを与えるようにしましょう。

つまり、この処理は弾にアタッチされているbullet.cs内に追記していきます。
(当然ですがEnemyにC#Scriptをアタッチしてその中にOnTriggerEnter2D
の処理を記載していっても全く問題ありません。)

ということでまずはOnTriggerEnter2Dの処理を記載していきます。
サンプルコードは以下です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        transform.Translate(Vector3.up * 10 * Time.deltaTime);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Enemy")
        {
            Destroy(collision.gameObject);
            Destroy(gameObject);
        }
    }
}

if(collision.collider.tag == “Enemy”)
で衝突相手が敵かどうか判定しています。
if文の中に入ったら敵をDestroy(消す)します。

次に敵に対してタグを付けましょう。
これはUnity上で以下のようにすればよいです。
(タグの追加はAdd Tag…から行います)

またOnTriggerEnter2Dを使う場合
敵・弾どちらのCollder 2Dの Is Triggerにチェックをつけておく必要があります。

これで一通り完了しました。
最後にゲームを実行してみましょう。

弾が発射され敵が消えることが確認できるかと思います。

最後に

いかがでしたでしょうか。
処理をすごいシンプルに記載していきました。

それぞれの機能はもっと色々な処理に使えるようなので、更に何が出来るか?を調べてみるとスキルが上がりそうですね。

タイトルとURLをコピーしました