Awake & Start
Awake はオブジェクト生成時に一度だけ走り(コンポーネントが無効でも実行されます)、Start は有効化後の最初のフレームで、シーン内のすべての Awake が終わってから実行されます。この実行順序を理解し、Singleton の設定とスクリプト間の安全な初期化パターンの書き方の基礎を学べます。
想像してみてください...
Awake は出勤前の個人準備——着替え、鍵を持つ、他者は不要。Start は朝のキックオフ会議——全員がすでに揃っている(全 Awake 完了)ので、チーム横断の仕事を割り当てられます(GameManager.Instance、他オブジェクト検索…)。
概念の詳細
Awake() はインスタンス生成時にちょうど一度呼ばれます——
コンポーネントが enabled = false でも。内部参照に最適:
_rb = GetComponent<Rigidbody>()。
Start() はコンポーネントが 有効になった後の最初のフレームで走ります。シーン内のすべての Awake() が すでに終わっているため、Start は Singleton、他オブジェクト検索、イベント登録に安全です。 無効化して再有効化しても、Start は再実行されません。
実行順序: Unity はまず全スクリプトの Awake、 次に全スクリプトの Start。スクリプト間の順序は未定義で、 Project Settings の Script Execution Order で指定しない限り決まりません。
ランタイム Instantiate: 生成されたオブジェクトも
Awake + Start を受けます。Awake は Instantiate() が戻る前、Start は次フレームの開始時です。
スクリプト間の実行順序
⚡ AWAKE フェーズ(最初のフレーム前)
GameManager.Awake()
_instance = this
PlayerCtrl.Awake()
_rb = GetComponent()
EnemyAI.Awake()
_nav = GetComponent()
🚀 START フェーズ(最初のフレーム)
GameManager.Start()
LoadLevel(1)
PlayerCtrl.Start()
GameManager.Instance ✅
EnemyAI.Start()
FindPlayer() ✅
ハンズオン手順
Awake:自己初期化
GetComponent<T>() をキャッシュ、プライベートフィールド初期化、Singleton 設定。他オブジェクトは呼ばない。
Start:外界と接続
GameManager.Instance、FindObjectOfType<T>()、イベント登録を使う。
必要なら Script Execution Order
Edit → Project Settings → Script Execution Order → より早く走らせたいスクリプトを上へ。
スクリプト間の null を避ける
ScriptA.Awake がまだ Awake していない ScriptB に触ると null。横断アクセスは Start で。
インタラクティブシミュレーター
スクリプトをシーンに追加し Load Scene を押すと、各スクリプトで Awake → Start の順に発火します。
Scripts in Scene
Execution Log
スクリプトを追加して Load Scene...
コード例
基本Awake で Singleton、他コンポーネントは Start で接続。
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
void Awake()
{
// Singleton setup — runs before every Start()
if (Instance != null) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
}
}
public class PlayerController : MonoBehaviour
{
private Rigidbody _rb;
void Awake() => _rb = GetComponent<Rigidbody>();
void Start()
{
// Safe: GameManager.Awake() already finished
GameManager.Instance.RegisterPlayer(this);
}
}コード例
上級[DefaultExecutionOrder] 属性で Awake 順序を制御する。
using UnityEngine;
// Runs before other scripts (more negative = higher priority)
[DefaultExecutionOrder(-100)]
public class ServiceLocator : MonoBehaviour
{
public static ServiceLocator Instance { get; private set; }
private Dictionary<System.Type, MonoBehaviour> _services = new();
void Awake()
{
Instance = this;
// Auto-register every IService in the scene
foreach (var svc in FindObjectsOfType<MonoBehaviour>())
if (svc is IService)
_services[svc.GetType()] = svc;
}
public T Get<T>() where T : MonoBehaviour =>
_services.TryGetValue(typeof(T), out var s) ? s as T : null;
}
// Any script can fetch a service in Start:
// var gm = ServiceLocator.Instance.Get<GameManager>();📌 要点
- ▸Awake:自分を準備——他者不要
- ▸Start:シーンと接続——全 Awake の後
- ▸有効/無効の切替で Start は再実行されない
- ▸順序固定には
[DefaultExecutionOrder]
⚠️ よくあるミス
❌ Awake() 内で Singleton に触る
まだ Awake していない可能性 → NullReferenceException
✅ Singleton へのアクセスは Start()
❌ Singleton を Start() で作る
他スクリプトの Awake 完了時にまだ無い → null
✅ Singleton は必ず Awake() で作る