Menu
CoddyTech

OnEnableで購読する

CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 13/64。

破棄されたリスナーは、自分でイベントから抜けることはありません。イベントはメソッドを保持し続け、次の Invoke で破棄されたコンポーネントに対してそのメソッドを呼び出します。そのメソッドで最初に transform を使うと MissingReferenceException が発生し、例外が発生すると Invoke が終了するため、その後のリスナーもスキップされます。したがって、すべての += には -= が必要です。Unity には、そのためのメソッドの組み合わせとして OnEnable と OnDisable があります。

public class Guard : MonoBehaviour
{
    public Alarm alarm;

    void OnEnable()
    {
        alarm.OnTriggered += RunTo;
    }

    void OnDisable()
    {
        alarm.OnTriggered -= RunTo;
    }

    void RunTo(Vector3 spot)
    {
        transform.LookAt(spot);
    }
}

Unity は、SetActive(false) でオブジェクトをオフにしたとき、スクリプトを無効にしたとき、そしてオブジェクトを破棄したときに、OnDestroy の前に OnDisable を呼び出します。オブジェクトが再び有効になるたびに OnEnable が実行されます。この組み合わせなら、ガードは有効な間だけイベントをリッスンします。破棄されたガードはイベントから取り除かれ、カットシーンのためにオフにされたガードは警報を無視し、再びオンになるとまたリッスンします。

ほかにも、うまくいかない組み合わせが2つあります。Start に += を置き、OnDisable に -= を置くと、Start は一度しか実行されないため、オフにしてからオンにしたガードは二度とリッスンしません。OnEnable に += を置いて -= を置かないと、再び有効になるたびに RunTo が追加され、警報1回で2回呼び出されます。登録されていないメソッドを削除しても何も起こらないため、OnDisable の -= の前に確認する必要はありません。

challenge icon

チャレンジ

簡単

各村人が有効な間だけ、ベルの音を聞くようにします。

  1. Villager.csで、bell.OnRing += Hop;をStart()から新しいvoid OnEnable()に移動し、Start()を削除します。
  2. bell.OnRing -= Hop;を含むvoid OnDisable()を追加します。「確認」では、これをテストするためにCleoをオフにしてからオンにします。

「プレイ」を押して4回ベルを鳴らします。2回目の後にAnaが帰宅し、エラーは表示されません。その後、「確認」を押します。

自分で試してみよう

using UnityEngine;

public class Villager : MonoBehaviour
{
    public Bell bell;
    public int ringsToLeave = 3;
    public int hops;

    void Start()
    {
        bell.OnRing += Hop;
    }

    void Update()
    {
        // 跳ねた後、地面に戻る
        Vector3 p = transform.position;
        transform.position = new Vector3(p.x, Mathf.MoveTowards(p.y, 0.5f, 4f * Time.deltaTime), p.z);
    }

    void Hop(int ring)
    {
        hops++;
        transform.position += Vector3.up * 0.8f;
        if (hops == ringsToLeave)
        {
            Debug.Log(name + " goes home");
            Destroy(gameObject);
        }
    }
}

Unityのゲームアーキテクチャのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド