본문 바로가기
- Unity/let us all UNITE !

[Unity] Awake OnEnable Start

by david_동근 2025. 5. 17.

https://docs.unity3d.com/6000.0/Documentation/Manual/execution-order.html

위 이미지는 Order of execution for event functions (이벤트 메서드 순서)의 플로우차트 일부분으로,

이번 포스트는 Initialization 파트를 다루고 있습니다.

 


 

 

Awake OnEnable Start

MonoBehaviour에서 상속받아 사용할 수 있는 클래스 메서드로,

인스턴스의 초기화와 시작시 행동을 관리할 때 사용합니다

순서는 Awake → OnEnable → Start 입니다.

 

Awake()

새 오브젝의 인스턴스가 생성될 때, 첫빠따로 호출되는 메서드입니다.

항상 Start 함수 이전에 호출 됩니다.

만약 GameObject가 시작했는데 비활성화 상태일 경우엔, 활성화될 때까지 Awake()는 호출되지 않습니다.

 

게임이 시작될 때 호출하므로, 여러 객체에서의 Awake() 호출은 (isn't Manually) 간혹 주의가 필요한데,
A 객체에서는 B 객체의 Awake()가 이미 호출된 상태를 가정해서는 안된다고 합니다.

필요하다면 Start로 참조를 수행하는 것이 안전합니다.

(하지만, 공식문서에선 RunTime에서는 이를 강제할 수 없다고 하네요)

 

추가로 일시적인 필요로 리소스를 Awake에서 호출할 경우, 메모리에 계속 남기 때문에,

적절한 때 해제를 해 줘야합니다. (Destroy(), Resources.UnloadUnusedAssets() 등)

void Awake() {
    DavidsComponent = GetComponent<DavidsComponent>(); // 참조 설정 등
}

 

 

OnEnable()

말 그대로 객체가 활성화될때 호출되는 함수이며, 반대 개념은 OnDisable() 입니다.

인스턴스가 활성활 될 때마다 호출되는 메서드이기에 코드를 가볍게 작성하도록 신경써야 합니다.

 

게임 런타임 중, 오브젝트가 활성화 될 때, 어떤 이벤트가 발생하면 반응하도록 리스너 Subscribe을 해둡니다.

void OnEnable() {
    EventManager.OnWorkHard += Respond; // 리스너 subscribe (등록)
    StartCoroutine(AnythingWahtUwant());
}

void OnDisable() {
    EventManager.OnWorkHard -= Respond; // 리스너 해제
    StopAllCoroutines();
}

 

Event Listener 등록과 해제 (OnDisable()해주지 않을시 누수 현상 발생 가능) 를 해당 메서드에서 처리하며,

혹은 코루틴과 같은 주기 작업에 관해서도 OnEnable() 에서 관리해줄 수 있습니다.

void OnEnable() {
    StartCoroutine(WorkRepeatedly());
}

IEnumerator WorkRepeatedly() {
    while (true) {
        Debug.Log("어쩌구 저쩌구 바쁘다 바빠");
        yield return new WaitForSeconds(10f);
    }
}

void OnDisable() {
    StopAllCoroutines(); // 코루틴 멈추기
}

 

게임 실행 중 UI 상태 변경 등에도 사용한다고 합니다.

 

Start()

Update()의 첫 프레임이 호출되기 전에, 한번 호출됩니다.

Awake()와 마찬가지로, Start() 메서드에서도 초기화를 담당합니다.

 

Awake()와 비교하면 아래와 같습니다.

  Awake() Start()
초기화 컴포넌트 초기화 간단한 private 필즈 값 초기화
예시 GetComponent<>()... 게임 시작에 필요한 로직 구성 → ex) 플레이어 위치, 애니메이션 상태, 기타 미디어 트리거 상태 등
다른 객체 Awake 관계 다른 스크립트의 Awake()가 호출되기 전이라는 걸 보장할 수 없음 다른 객체의 Awake()에서 설정된 값에 의존하는 초기화 작업 가능, (즉, 다른 객체의 컴포넌트나 필드 참조 가능)
호출 시점 비활성화 상태여도 호출 활성화 상태일 때만

주의 사항으로 예시 코드 하나 보고 마치겠습니다.

// GameManager.cs
public class GameManager : MonoBehaviour {
    public string message;

    void Awake() {
        message = "Hello from Awake!";
    }
}
// UIManager.cs
public class UIManager : MonoBehaviour {
    void Start() {
        Debug.Log(FindObjectOfType<GameManager>().message); // 아주 바람직 해용!
    }
}

 

위 처럼 Start() 메서드가 다른 객체의 Awake() 참조를 문제없이 하였습니다.

하지만, 아래와 같이 작성하는 것은 위험합니다.

// UIManager.cs
public class UIManager : MonoBehaviour {
    void Awake() {
        Debug.Log(FindObjectOfType<GameManager>().message); // 메세지가 null일 가능성 있음
    }
}

 

위에서 말했 듯이, 여러 객체가 Awake() 메서드는 순서가 보장이 되지 않습니다.

 


 

저 같은 경우는 Awake()와 Start() 메서드의 차이가 단순 시작 초기화 프레임 뿐인 줄 알고,

명확한 구분없이 사용했었어요.

혹시나 저와 같은 실수가 있었던 분들 께서는, 이제부터라도 초기화 메서드들의 구분을 명확히 하여,

예쁘고 정갈한 코드를 작성하실 수 있기를 바라요. 감사합니다.

그럼 오늘도 좋은 하루 되시길 바라요~ *⋆꒰ঌ(⁎ᴗ͈ˬᴗ͈⁎)໒꒱⋆*