Awake & Start
Awake는 객체가 생성될 때(비활성이어도) 한 번 호출되고 Start는 활성화된 첫 프레임에 실행됩니다. 모든 Awake가 끝난 뒤 안전히 연결하며 Singleton·Script Execution Order·교차 참조를 다룹니다. 실무에서 바로 쓰는 패턴을 익힙니다.
상상해 보세요...
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 이후
- ▸enable/disable로 Start가 다시 돌지 않음
- ▸순서 고정에는
[DefaultExecutionOrder]
⚠️ 흔한 실수
❌ Awake() 안에서 Singleton 접근
Singleton이 아직 Awake 전일 수 있음 → NullReferenceException
✅ Singleton은 Start()에서 접근
❌ Start()에서 Singleton 생성
다른 스크립트 Awake가 끝날 때 Singleton이 아직 없음 → null
✅ Singleton은 항상 Awake()에서 생성