Unity ライフサイクルとスクリプト有効/無効イベント総まとめ
本資料では、Unity のスクリプトが「有効/無効」状態になるタイミングと呼び出されるイベントについて整理し、分かりやすくまとめます。
「インスペクタのチェックを外す(enabled = false
)状態でも呼ばれるイベント、呼ばれないイベントの一覧表」やフローチャート、そして最後にサンプルコードも掲載しています。
1. スクリプトの「有効/無効」とは?
- スクリプトの有効/無効
- Unity の
MonoBehaviour
を継承したクラスは、インスペクタのチェックボックスやenabled
フラグでアクティブ/非アクティブを切り替えることができます。 - このチェックを外した(
enabled = false
)状態 を「スクリプトが無効」と呼びます。
- Unity の
- GameObject のアクティブ/非アクティブ
gameObject.SetActive(true/false)
でオブジェクト自体をアクティブ/非アクティブに切り替えます。- GameObject 自体が非アクティブの場合、その配下のコンポーネントはすべて動作しなくなり、
Awake()
すら呼ばれません。
2. ライフサイクルイベントの一覧表
Unity の代表的なライフサイクルイベントと、「スクリプトが無効 (enabled = false
) でも呼ばれるか」を中心にまとめた表です。
イベント名 | 無効状態 (enabled=false ) でも呼ばれるか? | 呼ばれるタイミング | 備考 |
---|---|---|---|
Awake() | はい (※1) | コンポーネントがロードされた直後 (GameObject がアクティブの場合) | – スクリプトが無効でも一度だけ呼ばれる – GameObject 自体が非アクティブだと呼ばれない |
OnEnable() | いいえ | スクリプトが有効化された瞬間 | – enabled = true 、またはインスペクタでチェックを入れたタイミング |
Start() | いいえ | スクリプトが初めて有効になったフレームの開始時に 1 回 | – 一度呼ばれると再度有効化しても再呼び出しされない(同オブジェクト内では初回のみ) |
Update() / FixedUpdate() / LateUpdate() | いいえ | 毎フレーム(または物理ステップ、描画後フレーム) | – 有効な間のみ呼ばれる |
OnGUI() | いいえ | GUI イベントごとに(フレーム内で複数回呼ばれる場合あり) | – 有効な間のみ呼ばれる |
OnDisable() | はい | スクリプトが無効化される瞬間 ( enabled = false やインスペクタチェックを外した時) | – GameObject を非アクティブにするときにも呼ばれる – 無効になる「直前」に呼ばれる |
OnDestroy() | はい | オブジェクトやコンポーネントが破棄されるとき | – 有効/無効に関係なく必ず呼ばれる |
OnTriggerEnter(), OnTriggerStay() etc. | いいえ | 当該トリガー(衝突)イベントが発生したタイミング | – スクリプトが有効な間のみ衝突判定が処理され、コールバックが呼ばれる |
OnCollisionEnter(), OnCollisionStay() etc. | いいえ | 当該コリジョン(物理衝突)イベントが発生したタイミング | – スクリプトが有効な間のみ衝突判定が処理され、コールバックが呼ばれる |
OnMouseDown(), OnMouseUp() etc. | いいえ | マウス・タッチイベントが発生したタイミング | – スクリプトが有効な間のみ呼ばれる |
(※1) ただし、GameObject がシーン読み込み時点で 非アクティブ (
SetActive(false)
) の場合はAwake()
も呼ばれず、後でSetActive(true)
にされたタイミングで初めて呼ばれます。
3. 有効化・無効化で呼ばれるイベントの流れ
3.1 有効化の流れ
- オブジェクト生成/シーン読み込み時
- GameObject がアクティブで読み込まれるとき、
Awake()
が呼ばれる(スクリプトが無効でも一度は呼ばれる)。
- GameObject がアクティブで読み込まれるとき、
- スクリプトが有効になる瞬間
OnEnable()
が呼ばれる(enabled = true
やインスペクタでチェックをオンにする)。- 初回であれば、次のフレーム開始時に
Start()
が呼ばれる(1 度だけ)。
- 有効な間
- 毎フレームごとに
Update()
/FixedUpdate()
/LateUpdate()
などが呼ばれ、OnTriggerEnter()
やOnCollisionEnter()
、OnMouseDown()
など各種イベントも受け付ける。
- 毎フレームごとに
3.2 無効化の流れ
- スクリプトが無効化される瞬間
OnDisable()
が呼ばれる(enabled = false
やインスペクタでチェックを外す、またはgameObject.SetActive(false)
により間接的にスクリプトが無効扱いになる場合も同様)。
- 無効状態
Update()
やFixedUpdate()
、衝突やマウスなどのイベントは呼ばれない。
- 破棄されるタイミング
OnDestroy()
が呼ばれる(有効/無効に関係なく必ず)。
4. フローチャート(ASCII 図)
以下は、MonoBehaviour がアタッチされた GameObject がアクティブな状態でシーンに存在し、スクリプトが有効化・無効化・破棄されるまでの大まかな流れを図示したものです。
+-----------------------------------+
| [Awake()] |
| (GameObjectがアクティブ&ロード時) |
+----------------+------------------+
|
v
+------------+
| OnEnable() | (スクリプトが有効化された)
+------------+
|
| (初回のみ)
v
+-----------+
| Start() | (有効化後、最初のフレームで1回)
+-----------+
|
v
+-------------------------------------+
| Update()/FixedUpdate()/LateUpdate() |
| (スクリプトが有効な間、毎フレーム) |
+-------------------------------------+
|
v
+--------------------+
| OnDisable() |
| (スクリプト無効化) |
+--------------------+
|
v
+--------------------+
| OnDestroy() |
| (破棄時に呼ばれる) |
+--------------------+
5. よくある質問(FAQ)と注意点
- 「スクリプトが無効でも
Awake()
は呼ばれる」って本当?- はい、ただし GameObject がアクティブ でシーンに読み込まれた(または生成された)場合に限ります。
- もし GameObject 自体が非アクティブなら、
Awake()
も呼ばれず、後でSetActive(true)
になったタイミングで初めて呼ばれます。
Start()
は何度でも呼ばれるの?- いいえ、一度だけです。同一オブジェクト上で再度有効化しても、基本的に
Start()
は再呼び出しされません(OnEnable()
は有効化のたびに呼ばれます)。
- いいえ、一度だけです。同一オブジェクト上で再度有効化しても、基本的に
- 無効化したら
Update()
だけでなく衝突イベントなども止まるの?- はい。
OnCollisionEnter()
、OnTriggerEnter()
、OnMouseDown()
といったイベントも、スクリプトが有効な間 だけコールバックされるものです。
- はい。
- 破棄(
Destroy()
)されたとき、無効だとOnDestroy()
は呼ばれない?- いいえ。無効・有効に関係なく、破棄されるときは必ず
OnDestroy()
が呼ばれます。リソースの解放やグローバル変数の後処理などはここで行います。
- いいえ。無効・有効に関係なく、破棄されるときは必ず
6. サンプルコード
6.1 コンソールで各イベントの呼ばれ方を確認するコード
以下のサンプルスクリプトを GameObject にアタッチし、インスペクタの有効/無効切り替えや Destroy()
を試すと、各イベントが実行されたタイミングでログが出力されます。
(GameObject も含めてアクティブ/非アクティブを切り替えれば、Awake()
や OnEnable()
の呼ばれ方も確認可能です)
using UnityEngine;
public class LifeCycleLogger : MonoBehaviour
{
private void Awake()
{
Debug.Log($"[Awake] {gameObject.name} - enabled:{enabled}");
}
private void OnEnable()
{
Debug.Log($"[OnEnable] {gameObject.name} - enabled:{enabled}");
}
private void Start()
{
Debug.Log($"[Start] {gameObject.name} - enabled:{enabled}");
}
private void Update()
{
// 毎フレームの呼び出しを軽めに示したい場合はコメントアウトを外す
// Debug.Log($"[Update] {gameObject.name} - enabled:{enabled}");
}
private void OnDisable()
{
Debug.Log($"[OnDisable] {gameObject.name} - enabled:{enabled}");
}
private void OnDestroy()
{
Debug.Log($"[OnDestroy] {gameObject.name}");
}
}
使い方
- 上記スクリプトを
LifeCycleLogger.cs
などの名前で作成。 - 空の GameObject(または任意のオブジェクト)にアタッチ。
- 再生モード(Play)にして、インスペクタでスクリプトのチェックを外したり、GameObject をアクティブ/非アクティブに切り替えたりしてみる。
- コンソールにどのタイミングでメッセージが出るかを確認する。
6.2 別オブジェクトを生成&破棄する簡易サンプル
こちらは別オブジェクトの生成 → 有効/無効 → 破棄 の流れを一括でテストするためのサンプルです。
using UnityEngine;
public class TestSpawner : MonoBehaviour
{
public GameObject prefab;
private GameObject spawnedObject;
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
// プレハブからインスタンスを生成
spawnedObject = Instantiate(prefab, Vector3.zero, Quaternion.identity);
Debug.Log($"Spawned {spawnedObject.name}");
}
if (Input.GetKeyDown(KeyCode.Alpha2) && spawnedObject != null)
{
// スクリプトを無効化
var script = spawnedObject.GetComponent<LifeCycleLogger>();
if (script != null)
{
script.enabled = false;
Debug.Log($"Disabled script on {spawnedObject.name}");
}
}
if (Input.GetKeyDown(KeyCode.Alpha3) && spawnedObject != null)
{
// スクリプトを有効化
var script = spawnedObject.GetComponent<LifeCycleLogger>();
if (script != null)
{
script.enabled = true;
Debug.Log($"Enabled script on {spawnedObject.name}");
}
}
if (Input.GetKeyDown(KeyCode.Alpha4) && spawnedObject != null)
{
// オブジェクトを破棄
Destroy(spawnedObject);
Debug.Log($"Destroyed {spawnedObject.name}");
}
}
}
使い方
LifeCycleLogger
をアタッチしたプレハブ(例:MyPrefab
) を用意。TestSpawner
を適当なシーンのオブジェクトにアタッチし、prefab
フィールドに上記プレハブを割り当てる。- プレイ中に以下のキーを押して挙動を確認する:
- [1] → プレハブを生成 (
Awake()
→OnEnable()
→Start()
が順に呼ばれる) - [2] → スクリプトを無効化 (
OnDisable()
が呼ばれる) - [3] → スクリプトを再度有効化 (
OnEnable()
が呼ばれる。Start()
は呼ばれない) - [4] → 破棄 (
OnDestroy()
が呼ばれる)
7. まとめ
- 「スクリプトが無効 (
enabled=false
) でも呼ばれる」主なイベントAwake()
(GameObject がアクティブな状態でロード/生成されたとき)OnDisable()
(有効→無効へ切り替わる瞬間)OnDestroy()
(破棄時、状態問わず必ず呼ばれる)
- 「スクリプトが無効状態では呼ばれない」イベント
OnEnable()
,Start()
,Update()
,FixedUpdate()
,LateUpdate()
,OnGUI()
, 各種衝突/マウスイベント など
今回のサンプルコードで、実際にコンソールログを確認してもらえれば、「いつどのイベントが呼ばれているか」を体感的に把握できます。Awake()
が「スクリプト無効でも一度は呼ばれる」点 と、OnDestroy()
が「最終的に必ず呼ばれる」 点は特に抑えておくと、初期化や破棄処理でのトラブルを防ぐことができます。
以上、「Unity ライフサイクルとスクリプト有効/無効イベント総まとめ」でした。ぜひ開発時の参考にしてみてください。
ディスカッション
コメント一覧
まだ、コメントがありません