Unity のライフサイクルを学ぼう!【Awake, Start など】

Unityのライフサイクルを学ぼう

Unity のゲーム開発において、理解しておくべき重要な概念の一つに「ライフサイクル」というものがあります。Unity にはオブジェクトやシーンなどが持つ独自のライフサイクルが存在し、それを理解することでより効率的にゲームを開発することができます。

この記事では、Unity のライフサイクルで重要な関数をいくつか紹介します。

Unity のライフサイクルとは?

Unity のライフサイクルとは、ゲームオブジェクトの生成から破棄までの一連のプロセスのことを指します。

Unityのライフサイクル

ライフサイクルの流れに沿って決まった関数が順番に呼び出されるので、どのタイミングでどんな関数が呼び出されるかを覚えておくことでゲームオブジェクトを制御できます。

ライフサイクルの各関数について解説

Awake()

ゲームオブジェクトが生成される際に一度だけ呼ばれます。

最初に呼び出される関数で、オブジェクトの初期化を行うのに適しています。もし初期化時にゲームオブジェクトが無効である場合、有効になるまで Awake() は呼び出されません。

OnEnable()

スクリプトが有効化されたときに呼び出されるメソッドです。

つまり、スクリプトがアタッチされたオブジェクトがアクティブになったときや、SetActive(true)が呼ばれたときなどに呼び出されます。

void OnEnable()
{
    Debug.Log("オブジェクトがアクティブ化されました。");
}

Start()が一度しか呼ばれないのに対して、OnEnable()オブジェクトがアクティブになるたびに呼ばれるため、より柔軟な処理が書ける利点があります。

初めて使う場合はStart()との違いに注意して使い分けるようにしましょう。

Start()

オブジェクトの初期化時に一度だけ呼び出され、オブジェクトが有効になった直後に実行されるメソッドです。

このメソッドは、Awake()OnEnable() メソッドの後に呼び出されます。

Start メソッドはオブジェクトが初期化される際に実行されるため、一度だけ呼び出されることが保証されています。そのため、オブジェクトが持つプロパティやフィールドの初期化、各種コンポーネントの設定や初期化、各種リソースのロードなど、オブジェクトが動作するために必要な初期化処理を実装するのに適しています。

void Start()
{
    Debug.Log("アプリケーションが開始されました。");
} 

例えば、オブジェクトが有効になってから初めてアニメーションを再生する必要がある場合、Start メソッドを使用してアニメーションの初期化処理を実装することができます。また、オブジェクトが有効になってから初めて音声を再生する必要がある場合にも、Start メソッドを使用した音声の初期化処理が実装可能です。

FixedUpdate()

物理演算を扱うためのメソッドです。Update はフレーム毎に呼ばれるのに対し、このメソッドはフレームレートに依存しない時間間隔で呼び出されます。

通常、Update メソッドはフレームレートに依存して呼び出されるため、フレームレートが不安定な場合は物理演算の挙動が不安定になる可能性があります。しかし、FixedUpdate メソッドは一定の時間間隔で呼び出されるため、フレームレートが不安定でも物理演算の挙動を一定に保つことができます。

FixedUpdate メソッドは、物理的な力を加える場合や剛体の速度を制御する場合などで活用されます。また、Rigidbody コンポーネントを使用しているオブジェクトについては、FixedUpdate メソッドで物理演算を処理することが推奨されます。

以下は FixedUpdate メソッドを使ったサンプルコードです。

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    private Rigidbody rb;
    public float Speed;

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

    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(moveHorizontal, 0f, moveVertical);

        rb.AddForce(movement * Speed);
    }
}

Update()

ゲーム実行中に毎フレーム呼ばれる関数で、ゲームオブジェクトの動作を制御するために利用されます。

Unityでは、ゲームオブジェクトの移動や回転、アニメーションなど、ほとんどの動作は Update メソッド内で処理されます。

void Update()
{
    // オブジェクトを前方に移動させる
    transform.position += transform.forward * Time.deltaTime * speed;
}

Updateメソッドはフレーム毎に呼び出されるため、フレームレートによって処理速度が変わります。そのため、Updateメソッド内での処理が重いと、ゲームのパフォーマンスに影響を及ぼすことがあります。扱いには注意しましょう。

LateUpdate()

Update() メソッドの処理が終了した後、カメラが描画される前に実行されます。

Update メソッドが実行された後に LateUpdate が呼び出されるため、LateUpdate ではカメラの移動やアニメーションの再生など、Update で処理すると遅れるような処理を行うことができます。

void LateUpdate()
{
    // カメラの位置をプレイヤーの位置に合わせる
    Vector3 cameraPosition = transform.position;
    cameraPosition.z = -10f;
    Camera.main.transform.position = cameraPosition;
}

例えばカメラを追跡するスクリプトを作成する場合、Update メソッドでカメラの座標を更新すると、移動が滑らかでなくなることがあります。これは Update メソッドがフレームレートに依存するため、フレームレートが低下するとカメラの移動速度が変わってしまうためです。

一方 LateUpdate メソッドを使用すると、カメラが追跡するオブジェクトの座標が更新された後にカメラを移動するため、滑らかな追跡が可能になります。

OnDisable()

オブジェクトが無効化されたときに呼び出されるメソッドです。

このメソッドは、オブジェクトがシーンから削除される場合や SetActive(false) メソッドで明示的に無効化された場合に呼び出されます。

private void OnDisable()
{
    Debug.Log("MyComponent is disabled");
}

上記のコードは、MyComponentクラスが無効化された時に "MyComponent is disabled" というログを表示する簡単な例です。

上記コードを使用すると、以下のようにコンポーネントを無効化したときにログが表示されます。

MyComponent myComponent = GetComponent<MyComponent>();
myComponent.enabled = false;

OnDestroy()

オブジェクトが破棄される直前に呼び出されるメソッドです。つまり、オブジェクトのインスタンスが削除される前に実行されます。

このメソッドは、主にオブジェクトが破棄される前に必要な処理を実行するために使用されます。例えば、オブジェクトが使用しているリソースを解放する、保存されていたデータを破棄する、他のオブジェクトとの接続を切断するなどの作業が挙げられます。

private void OnDestroy()
{
    // オブジェクトが破棄される前に実行する処理を記述する
    Debug.Log("Object is destroyed!");
}

また、このメソッドはスクリプトがアタッチされたオブジェクトが削除されたときに自動的に呼び出されますが、スクリプトがアタッチされたオブジェクトが破棄されない場合(例えば、シーンがアンロードされる場合)は、OnDestroy メソッドは呼び出されません。

参考図書

参考リンク