norablog-techのブログ

このブログは、自分の忘備録的にアウトプットするためのブログとなっております。

【Unity】ゲーム画面外に飛び出た弾を消す

変更:
2022/01/25 変数名を"アッパーキャメル"から、すべて小文字に修正。

 

前回、UnityのPreFab機能を使って大量の弾を生成し、スペースキーを叩く度に発射するプログラムを作成しました。
しかし、生成された弾はどこまでも飛んで行き、ゲームのメモリー上に残ってしまいます。

弾を消す(メモリーを開放する)方法を考えます。
以下の2通りを試します。

 

その1:Y軸方向に一定以上離れた弾を破壊(メモリーの開放)する

 "BulletController.cs"のUpdate()関数に以下を追加します。

 

        if (transform.position.y > 6)
        {
            Destroy(gameObject);
        }

※いきなり出てきている"gameObject"ですが、Unityの概念として、このゲーム内のすべての"gameObject"を指し示していると理解しています。
※単純で分かりやすい方法です。

 

スクリプトを保存し、ゲームを実行してみてください。

ヒエラルキー上に残っていた"Bullet(clone)"が、弾がゲーム画面から出ると消えるのが確認できすはずです。
これでも十分、実用に耐えます。

確認が終わったら、次の方法を試すため、追加した部分はコメントアウトしておいてください。

BulletPreFabController.cs

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

public class BulletPreFabController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //BulletPreFabの位置を1Sec毎に1fだけ+Y方向(上)に動かす
        transform.position += new Vector3(
                0f,
                1f * Time.deltaTime,
                0f
            );

        //追加:Y軸方向に一定以上離れた弾("gameObject")を破壊(メモリーの開放)する
        if (transform.position.y > 6)
        {
            Destroy(gameObject);
        }

    }
}

 

その2:必要な各"gameObject"に、"Box Collider 2D"、"Rigidbody 2D"、"Capsule Collider 2D"を設定し、メソッド?"OnTriggerExit2D"を使い衝突判定を行います。
※ほかに"OnTriggerEnter2D"、"OnTriggerStay2D"というメソッドもあります。"Collider"と、"接触"したとき、"接触"中、"離れた"ときというように使い分けるようです。

1)"空のオブジェクト"をヒエラルキー状に新規作成します。
 "Bounds(境界、果て)"という概念が"Collider"にあるので、"Boundary(境界)"という名前にします。

 

2)"コンポーネントの追加"より、"Box Collider 2D"を追加します。
 "トリガーにする"にチェックを入れ、"サイズ"はほぼゲーム画面に合わせました。
 一旦ゲーム画面の外に飛び出してもまた戻ってくるような動きをするオブジェクト(弾や敵機など)があれば、少し大きめにしてもよいと思います。

 

3)"コンポーネントの追加"より、"BoundaryController"を追加します。
 名前は区別がつけば何でもよいです。今回はスクリプトを初めのほうで"~~Controllerとする"という勝手に決めた命名規則にしたがいました。

以下の一文を、void Start()の前に挿入します。

private void OnTriggerExit2D(Collider2D collision)
    {
        Destroy(collision.gameObject);
    }

 

BoundaryController.cs

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

public class BoundaryController : MonoBehaviour
{
    //追加:"Boundary"から出て行った"gameObject"をDestroy(破壊=メモリーの開放)する。
    private void OnTriggerExit2D(Collider2D collision)
    {
        Destroy(collision.gameObject);
    }


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

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

4)PreFabsフォルダー内の"Bullet.prefab(プレハブアセット)"の"インスペクター"に"コンポーネントの追加"より、"Rigidbody 2D"を追加します。
 "ボディタイプ"を"キネマティック"(物理演算を使う場合は"ダイナミック"を使うようです)に変更します。

 

5)同じく"コンポーネントの追加"より、"Capsule Collider 2D"を追加します。
 "Collider"の設定画面に遷移するので、(しない場合はPreFabsフォルダー内の"Bullet"をダブルクリック)"サイズ"を適当な大きさに変更します。
 今回は、"X->0.2,Y->0.5"に設定しました。

※こちらのほうがUnityの機能をうまく使っていて、各gameObjectのスクリプト(コード)をいじらずに済みますね。
 汎用性が高く、ゲーム構成の見通しが良くなるように思います。

 

youtu.be

 

今回はここまでです。

一歩一歩、進めて行きたいと思います。

ではでは。