생명주기 [2]
Awake(), OnEnable(), OnDisable(), Start()
Awake()
특징
1. 반드시 Start 함수 전에 호출된다.
Scene 에 Empty 오브젝트를 생성 후, 아래의 스크립트를 컴포넌트로 추가한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
public class Test : MonoBehaviour
{
void Awake()
{
Debug.Log("Awake");
}
void OnEnable()
{
Debug.Log("OnEnable");
}
void Start()
{
Debug.Log("Start");
}
}
게임을 실행시키면, 아래의 사진과 같이 순서대로 호출되는 것을 볼 수 있다.
2. Scene 에 있는 모든 객체에 대해 호출된다.
게임 오브젝트 4 개를 배치한 뒤, 위의 Test.cs 스크립트를 컴포넌트로 추가한다.
게임을 실행시키면, 아래의 사진과 같이 Awake 가 4번 호출되는 모습을 볼 수 있다.
단, 유니티에서는 같은 씬에 있는 여러 오브젝트들의 Awake 호출 순서를 보장하지 않는다.
순서를 제어하고 싶다면 Edit → Project Settings → Script Execution Order 에서 설정할 수 있다.
하지만 이것은 스크립트 단위이고 오브젝트 단위가 아니라서, 같은 스크립트를 여러 오브젝트에 붙였을 땐 제어가 어렵다.
3. 함수는 게임이 실행된 이후 스크립트 당 최초 1 회만 호출된다.
Awake 함수는 게임 오브젝트가 파괴되고 재생성 하는것이 아닌 이상 단 한번만 호출된다.
아래의 사진을 보면, 스크립트를 껐다가 켜는 행위를 반복해도 호출이 되지않는 모습을 볼 수 있다.
4. 게임 오브젝트가 활성화 되어있다면, Awake 함수는 반드시 호출된다.
다르게 말해서, 스크립트가 활성화되어 있지 않더라도 Awake 는 호출된다.
아래와 같이 스크립트를 비활성화 한다.
게임을 실행하면, 스크립트가 꺼져있음에도 Awake 함수가 호출된 것을 확인할 수 있다.
Caution
-
Awake함수 내에 많은 연산을 하게 되면 게임 시작 전 로딩시간이 길어지게 된다.
그래서 최대한Awake내의 함수는 경량화 시키는 것이 좋다. - 여러 게임 오브젝트에서
Awake함수가 호출하는 경우는, 호출 순서는 보장받을 수 없다.
그래서A 객체에서B 객체의Awake함수를 호출된 상태로 가정해선 안된다. -
Awake는 해당 게임 오브젝트가 파괴 되기 전까진 메모리상에서 계속 남아있게 된다.
그래서Awake내에서 텍스처나 사운드 등을 불러왔을 때, 리소스들은 적절한 시점에서 해제되어야 한다. - 만약 두개의 게임 오브젝트가 서로를 참조해야한다면, 둘 중 하나는
Start함수 내에서 참조를 실행하는 것이 안전하다.
Tip
- 객체의 컴포넌트를 참조할 경우엔
Awake에서 참조하는 것이 일반적이다. - 싱글톤 패턴을 적용할 때 보통
Awake함수에서 로직을 처리한다.
OnEnable()
특징
OnEnable 함수는 스크립트, 혹은 게임 오브젝트가 활성화 될 때 마다 호출된다.
아래의 사진을 보면 체크박스를 껐다 켤 때 마다 OnEnable 의 호출횟수가 늘어나는 것을 볼 수 있다.
Caution
-
OnEnable은Start함수 전에 호출되므로,Start함수가 인지하기 전의 기능들을 호출해선 안된다. -
OnEnable은 게임 오브젝트, 혹은 스크립트 컴포넌트가 활성화 될 때 마다 호출되므로,
무거운 연산 혹은 긴 시간을 사용하는 알고리즘 또는 로직을 포함시키면 게임 성능에 악영향을 끼칠 수 있다. -
OnEnable내의 로직은 최대한 간결하게 유지하도록 신경쓰는 것이 좋다.불필요한 연산 및 호출 최소화
Tip
- 이벤트 리스너를 등록하고 해제하는 패턴으로 활용할 수 있다.
- 필요한 리소스를 동적으로 불러오고,
OnDisable로 해당 리소스를 해제하는 패턴으로
메모리 관리 및 성능 최적화를 할 수 있다.
OnDisable()
특징
OnDisable 함수는 OnEnable 과 반대로, 스크립트나 게임 오브젝트가 비활성화 됐을 때 호출된다.
게임 오브젝트가 파괴 되었을 때도 실행된다.
생명주기를 보면 OnDisable 이후에 바로 OnDestroy 가 호출되는 것을 볼 수 있다.
조금 더 상세하게 말하자면 비활성화가 되는 과정 이 있어야 실행이 되는 것이다.
스크립트가 처음부터 비활성화 인 상태에서는 OnDisable 이 호출되지 않는다.
TestCase 1
- 게임 오브젝트 및 스크립트 컴포넌트가 활성화 되어있는 상태로 게임실행.
- 스크립트 컴포넌트를 비활성화 함 → 예상대로
OnDisable함수 호출됨. - 이 상태에서 게임오브젝트도 비활성화 하면 호출되는가? →
OnDisable호출 안됨.
TestCase 2
- 게임 오브젝트 및 스크립트 컴포넌트가 활성화 되어있는 상태로 게임실행.
- 스크립트 컴포넌트를 비활성화 함 →
OnDisable함수 호출됨. - 게임 오브젝트 비활성화 → 위에서 진행한
TestCase 1과 똑같이 호출 안됨. - 게임 오브젝트를 다시 활성화.
- 게임 오브젝트를 다시 비활성화 → 이때는
OnDisable이 호출되는가?
→ 안됨.활성화 상태의 스크립트 컴포넌트가 비활성화 될 때호출되는 것.
Start()
특징
-
Start함수는Awake와OnEnable함수가 호출 된 뒤에 이루어진다. -
Scene에 배치된 **모든 객체의 Awake 함수와 OnEnable 함수가호출 되고 나서,Start함수가 호출된다. - 컴포넌트 활성화 된 순간을 기준으로, 첫번째 프레임가 업데이트 전에 호출된다.
-
Awake와 마찬가지로 객체에 대해서 최초1회만 호출되기 때문에, 객체의 초기화 작업에 주로 사용된다.
Awake VS Start
| 항목 | Awake | Start |
|---|---|---|
| 호출 조건 | 게임 오브젝트가 활성화 상태이면, 스크립트가 비활성이어도 호출됨 |
게임 오브젝트가 활성화 + 스크립트도 활성화 상태일 때만 호출됨 |
| 호출 시점 | 오브젝트 생성 직후, 모든 Awake가 먼저 호출됨 | 모든 Awake 호출 후, 프레임 시작 시점에 호출 |
| 주요 용도 | 자기 자신의 컴포넌트 초기화 및 참조 | 다른 객체나 외부 리소스에 대한 참조 |
| 싱글톤 구현 | Awake에서 구현하는 것이 일반적 | 다른 객체에서 먼저 접근 시 문제 생길 수 있음 |
| 상호 참조 안정성 | 불안정 | 상대적으로 안정적 |
Tip
- 보통 게임 로직의 초기세팅을 담당한다.
- ex) 캐릭터의 체력, 스탯, 초기 위치, 스테이지의 시작상태, 초기 애니메이션 등





