見出し画像

Unityのイベント関数④ | OnDisable・OnDestroy・OnBecameInvisible をわかりやすく解説

Unityでは、ゲーム中にオブジェクトが表示されたり、消えたり、画面外に出たりすることがあります。

たとえば、

  • 敵を倒したとき

  • 弾が画面外に出たとき

  • アイテムを非表示にしたとき

  • シーンを切り替えたとき

このようなタイミングで自動的に呼ばれるイベント関数があります。

今回は、

  • OnDisable

  • OnDestroy

  • OnBecameInvisible

の3つを解説します。



OnDisableとは

OnDisable は、オブジェクトやスクリプトが無効になったときに呼ばれるイベント関数です。

void OnDisable()
{
    Debug.Log("OnDisableが呼ばれました");
}

たとえば、次のようにオブジェクトを非表示にしたときに呼ばれます。

gameObject.SetActive(false);

また、Inspectorでスクリプトのチェックを外して無効にしたときにも呼ばれます。

OnDisableが呼ばれる主なタイミング

  • オブジェクトを SetActive(false) にしたとき

  • スクリプトを無効にしたとき

  • シーン切り替えなどでオブジェクトが無効になるとき

「使わなくなった」「一時的に止めた」というタイミングで呼ばれる、と考えると分かりやすいです。

OnEnableで復活

SetActive(true) で再度有効にしたときに呼ばれるイベント関数は、OnEnable() です。

void OnEnable()
{
    Debug.Log("オブジェクトが有効になりました");
}

OnEnable()関数は、以前開設した「Unityのイベント関数② | Awake・OnEnable・Startの違いを徹底解説」で詳しく説明していますので、合わせてご参照ください。


OnDestroyとは

OnDestroy は、オブジェクトが削除されるときに呼ばれるイベント関数です。

void OnDestroy()
{
    Debug.Log("OnDestroyが呼ばれました");
}

たとえば、次のようにオブジェクトを削除したときに呼ばれます。

Destroy(gameObject);

OnDestroyが呼ばれる主なタイミング

  • Destroy(gameObject) で削除されたとき

  • シーン切り替えでオブジェクトが破棄されるとき

  • ゲーム終了時にオブジェクトが破棄されるとき

OnDisable が「無効になったとき」なのに対して、OnDestroy は「完全に削除されるとき」です。


OnBecameInvisibleとは

OnBecameInvisible は、オブジェクトがカメラに映らなくなったときに呼ばれるイベント関数です。

void OnBecameInvisible()
{
    Debug.Log("画面から見えなくなりました");
}

たとえば、弾が画面外に出たときや、敵がカメラの外に出たときなどに使えます。

ただし、正確には「画面外に出たとき」ではなく、カメラに映らなくなったときです。

そのため、カメラに映る Renderer が必要です。
SpriteRenderer や MeshRenderer などが付いているオブジェクトで使います。


使い分けのイメージ

簡単にまとめると、

  • 一時的に無効になる → OnDisable

  • 完全に削除される → OnDestroy

  • カメラに映らなくなる → OnBecameInvisible

という使い分けです。


サンプル1:スペースキーでオブジェクトの有効・無効を切り替える

まずは、表示・非表示を切り替えたいオブジェクトに付けるスクリプトです。

using UnityEngine;

public class DisableSample : MonoBehaviour
{
    void OnEnable()
    {
        Debug.Log("オブジェクトが有効になりました");
    }

    void OnDisable()
    {
        Debug.Log("オブジェクトが無効になりました");
    }
}

このスクリプトを、表示・非表示を切り替えたいオブジェクトに付けます。

次に、スペースキーでそのオブジェクトを切り替えるためのスクリプトを作ります。

using UnityEngine;

public class ActiveSwitchSample : MonoBehaviour
{
    public GameObject targetObject;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            targetObject.SetActive(!targetObject.activeSelf);
        }
    }
}

このスクリプトは、空のオブジェクトなどに付けます。
そして、Inspectorで targetObject に、表示・非表示を切り替えたいオブジェクトを設定します。


処理の流れ

スペースキーを押すたびに、次のように切り替わります。

targetObject.SetActive(!targetObject.activeSelf);

targetObject.activeSelf は、現在そのオブジェクトが有効かどうかを表します。

つまり、スペースキーを押すたびに、有効 → 無効 → 有効 → 無効 というように切り替わります。


実行するとどうなるか

オブジェクトが無効になったときは、次のコードが呼ばれます。

void OnDisable()
{
    Debug.Log("オブジェクトが無効になりました");
}

再び有効になったときは、次のコードが呼ばれます。

void OnEnable()
{
    Debug.Log("オブジェクトが有効になりました");
}

サンプル2:敵が削除されるときに処理する

次は OnDestroy のサンプルです。

using UnityEngine;

public class Enemy : MonoBehaviour
{
    void OnDestroy()
    {
        Debug.Log("敵が削除されました");
    }

    public void Damage()
    {
        Destroy(gameObject);
    }
}

この例では、Damage() が呼ばれると敵オブジェクトが削除されます。

Destroy(gameObject);

によってオブジェクトが削除されるため、その直前に OnDestroy が呼ばれます。

敵を倒したときの後片付けや、ログ確認などに使えます。


サンプル3:画面外に出た弾を削除する

OnBecameInvisible は、弾や敵を画面外で削除したいときに便利です。

using UnityEngine;

public class Bullet : MonoBehaviour
{
    void Update()
    {
        transform.Translate(Vector3.right * 5f * Time.deltaTime);
    }

    void OnBecameInvisible()
    {
        Destroy(gameObject);
    }
}

このスクリプトでは、弾が右方向に移動します。

そして、カメラに映らなくなると、

Destroy(gameObject);

が実行されて、弾が自動で削除されます。

弾を出しっぱなしにすると、画面外に見えないオブジェクトがどんどん増えてしまいます。
そのため、画面外に出た弾を削除する処理はとても大切です。


サンプル4:アイテムを取ったら非表示にする

OnDisable は、削除ではなく「一時的に消す」処理にも使えます。

using UnityEngine;

public class Item : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            gameObject.SetActive(false);
        }
    }

    void OnDisable()
    {
        Debug.Log("アイテムが非表示になりました");
    }
}

プレイヤーがアイテムに触れると、

gameObject.SetActive(false);

でアイテムを非表示にします。

この場合、オブジェクトは削除されていないので OnDestroy ではなく OnDisable が呼ばれます。


OnDisableとOnDestroyの違い

OnDisable と OnDestroy は似ていますが、意味が違います。

OnDisable は、オブジェクトやスクリプトが無効になったときに呼ばれます。
一方、OnDestroy は、オブジェクトが完全に削除されるときに呼ばれます。

たとえば、下の場合は OnDisable が呼ばれます。

gameObject.SetActive(false);

一方、下の場合は OnDestroy が呼ばれます。

Destroy(gameObject);

また、Destroy で削除されるときは、無効化の流れも含まれるため、OnDisable が先に呼ばれ、そのあと OnDestroy が呼ばれることがあります。

OnDisableとOnDestroyの違い

OnBecameInvisibleの注意点

OnBecameInvisible は便利ですが、いくつか注意点があります。

まず、カメラに映る Renderer が必要です。
SpriteRenderer や MeshRenderer が付いていないオブジェクトでは、基本的に反応しません。

また、「画面外に出たら」ではなく「カメラに映らなくなったら」呼ばれます。
複数のカメラがある場合や、Sceneビューで表示されている場合など、思ったタイミングと違うことがあります。
最初は弾や敵など、シンプルなオブジェクトで使うのがおすすめです。


まとめ

今回は、オブジェクトが消える・見えなくなるときに使えるイベント関数を解説しました。

ゲーム制作では、オブジェクトを出したり消したりする処理がとても多く出てきます。

特に、

  • 敵を倒す

  • 弾を消す

  • アイテムを取る

  • 画面外のオブジェクトを片付ける

といった処理でよく使います。

最初は難しく考えすぎず、

  • 非表示なら OnDisable

  • 削除なら OnDestroy

  • 画面外なら OnBecameInvisible

と覚えておくと分かりやすいです。


Unity初心者向けの記事をテーマ別にまとめています。

▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもイベント関数を使って、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。

ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!