見出し画像

Unityのイベント関数② | Awake・OnEnable・Startの違いを徹底解説

前回の記事では、Unityでよく使うイベント関数として、以下の関数について説明しました。

  • Update

  • FixedUpdate

  • LateUpdate

これらは、ゲーム中に何度も繰り返し呼び出される関数です。

では、ゲームが始まった直後に一度だけ実行したい処理は、どこに書けばよいのでしょうか。

今回は、ゲーム開始直後によく使われるイベント関数、

  • Awake

  • OnEnable

  • Start

について説明します。

この3つはどれも「最初の方に呼ばれる関数」ですが、呼ばれるタイミングや使い方に違いがあります。



ゲーム開始直後に呼ばれるイベント関数

Unityでは、スクリプトに特定の名前の関数を書いておくと、決まったタイミングで自動的に呼び出されるイベント関数が用意されています。

たとえば、次のような関数です。

void Awake()
{
    Debug.Log("Awake");
}

void OnEnable()
{
    Debug.Log("OnEnable");
}

void Start()
{
    Debug.Log("Start");
}

このスクリプトを有効なGameObjectにつけてゲームを再生すると、基本的には次の順番で呼び出されます。

Awake → OnEnable → Start

まずはこの順番を覚えておくと、かなり理解しやすくなります。


Awakeとは

Awakeは、スクリプトが読み込まれたときに最初に呼ばれるイベント関数です。

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

Awakeは、Startよりも前に呼ばれます。

そのため、ゲーム開始前に必要な準備をしておきたい場合に使います。

たとえば、同じGameObjectについているコンポーネントを取得する処理などです。

public class PlayerController : MonoBehaviour
{
    Rigidbody rb;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }
}

この例では、Rigidbodyを取得して、変数rbに入れています。

このように、自分自身についているコンポーネントを取得する場合は、Awakeに書くことが多いです。


Awakeの主な使い道

Awakeは、主に次のような処理に使います。

・自分自身についているコンポーネントを取得する
・変数の初期設定をする
・他の処理より先に準備しておきたいものを用意する

たとえば、

void Awake()
{
    animator = GetComponent<Animator>();
    rb = GetComponent<Rigidbody>();
}

のような使い方です。

ポイントは、AwakeはStartより前に呼ばれるということです。

そのため、Startの中で使う変数を、先にAwakeで準備しておくことができます。


OnEnableとは

OnEnableは、そのGameObjectやスクリプトが有効になったときに呼ばれるイベント関数です。

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

AwakeとStartの間で呼ばれることが多いですが、OnEnableには大きな特徴があります。

それは『有効になるたびに呼ばれる』という点です。

Startは基本的に最初の1回だけ呼ばれます。

しかし、OnEnableはオブジェクトを一度OFFにして、もう一度ONにすると、再び呼ばれます。


OnEnableの動きを確認する

たとえば、次のようなスクリプトがあるとします。

void OnEnable()
{
    Debug.Log("有効になりました");
}

このスクリプトがついているGameObjectを、Inspectorで一度OFFにしてからONに戻すと、OnEnableが再び呼ばれます。


OnEnableの主な使い道

OnEnableは、主に次のような処理に使います。

・オブジェクトが表示された時に処理したい
・一度OFFにしたものをONに戻した時に処理したい
・イベント登録をしたい
・入力処理を有効にしたい

たとえば、敵キャラクターを一度非表示にして、あとから再び表示する場合を考えてみます。

このとき、敵が表示されるたびにHPを満タンに戻したい場合は、OnEnableが便利です。

public class Enemy : MonoBehaviour
{
    public int maxHp = 100;
    int hp;

    void OnEnable()
    {
        hp = maxHp;
    }
}

このように書いておくと、敵キャラクターが有効になるたびに、HPが最大値に戻ります。

Startに書いた場合は、基本的にゲーム開始時の1回しか実行されません。

void Start()
{
    hp = maxHp;
}

そのため、敵を一度OFFにしてから再びONにしても、Startはもう一度呼ばれません。

一方、OnEnableはONになるたびに呼ばれるため、再出現する敵や、何度も使い回すオブジェクトの初期化に向いています。

Start
→ 最初の1回だけ初期化したいとき

OnEnable
→ 表示されるたびに初期化したいとき

このように、OnEnableは「有効になったときに毎回行いたい処理」と相性が良いイベント関数です。


Startとは

Startは、ゲーム開始時に一度だけ呼ばれるイベント関数です。

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

まだ慣れないうちは『最初に一度だけ実行したい処理はStart』と考えておくと分かりやすいです。

たとえば、ゲーム開始時にスコアを0にしたり、HPを初期化したりするときに使います。

public class GameManager : MonoBehaviour
{
    int score;
    int hp;

    void Start()
    {
        score = 0;
        hp = 100;
    }
}

このように、Startはゲーム開始時の初期設定を書く場所としてよく使われます。

また、StartはAwakeより後に呼ばれるため、他のオブジェクトや、他のスクリプトの準備が終わったあとに処理を行いたい場合にも使いやすいです。

たとえば、シーンの中にあるPlayerオブジェクトを取得したい場合は、次のように書くことができます。

GameObject player;

void Start()
{
    player = GameObject.Find("Player");
}

GameObject.Find() は、シーンの中から指定した名前のGameObjectを探す命令です。

この例では、シーンの中から「Player」という名前のGameObjectを探して、変数playerに入れています。

また、他のスクリプト、つまり他のクラスを取得したい場合もあります。

たとえば、GameManagerというスクリプトを取得したい場合です。

GameManager gameManager;

void Start()
{
    gameManager = FindAnyObjectByType<GameManager>();
}

このように書くと、シーンの中にあるGameManagerクラスを探して、変数gameManagerに入れることができます。


Startの主な使い道

Startは、主に次のような処理に使います。

・ゲーム開始時の初期設定
・スコアやHPの初期化
・他のオブジェクトを取得する
・他のクラス、スクリプトを取得する
・他のオブジェクトが準備された後に行いたい処理
・最初に一度だけ表示したい処理

特に、他のオブジェクトや他のスクリプトを取得したい場合は、AwakeよりもStartに書いた方が分かりやすいことが多いです。

Awakeは自分自身の準備、Startは他のオブジェクトも含めたゲーム開始時の準備、と考えると整理しやすくなります。

Awake
→ 自分自身の準備

Start
→ ゲーム開始時の準備、他のオブジェクトの取得

Awake・OnEnable・Startの違い

ここで、3つの違いを整理してみましょう。

特に重要なのは、次の違いです。

Awake:Startより前に呼ばれる
OnEnable:有効になるたびに呼ばれる
Start:最初に一度だけ呼ばれる

使い分けのイメージ

初心者向けにざっくり分けると、次のようになります。

Awake
→ 自分自身の準備

OnEnable
→ 有効になった時に毎回やりたい処理

Start
→ ゲーム開始時に一度だけやりたい処理

もう少し具体的にすると、

RigidbodyやAnimatorを取得する
→ Awake

入力処理を有効にする
→ OnEnable

HPやスコアを初期化する、他のオブジェクトやクラスを取得する
→ Start

というイメージです。


実際のサンプル

次のサンプルでは、Awake、OnEnable、Startがどの順番で呼ばれるかを確認できます。

using UnityEngine;

public class EventTest : MonoBehaviour
{
    void Awake()
    {
        Debug.Log("1. Awake");
    }

    void OnEnable()
    {
        Debug.Log("2. OnEnable");
    }

    void Start()
    {
        Debug.Log("3. Start");
    }
}

このスクリプトをGameObjectにつけて実行すると、Consoleには次のように表示されます。

まずAwakeが呼ばれ、次にOnEnable、最後にStartが呼ばれます。


まとめ

今回は、Unityのイベント関数の中から、

  • Awake

  • OnEnable

  • Start

について説明しました。

それぞれの役割をまとめると、次のようになります。

Awake
→ 自分自身の準備をする

OnEnable
→ 有効になったときに毎回処理する

Start
→ ゲーム開始時に一度だけ処理する

特に、Awake、OnEnable、Startはどれもゲーム開始直後に呼ばれるため、最初は少し混乱しやすいです。

最後に、実際によくある使い分けをまとめます。

コンポーネントの取得
→ Awake

変数の初期化
→ Awake または Start

ゲーム開始時の表示設定
→ Start

有効化された時の処理
→ OnEnable

入力の有効化
→ OnEnable

入力の無効化
→ OnDisable

毎フレームの処理
→ Update

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

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


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

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

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

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