[Unity] 최초 실행되는 UnityMain 함수 만들기 (RuntimeInitializeOnLoadMethod 상세 순서 설명)
유니티 엔진에서 초기화를 하고싶어
유니티는 BuildSettings의 Scenes In Build 목록에 셋팅된 0번 인덱스 씬으로 시작하게 됨. 이 때 씬을 로드하면서 초기화도 같이 수행하게 되는데, 씬에 올라간, 씬의 Hierarchy 목록의 GameObject 들의 Awake와 Start의 호출 순서가 보장되지 않음.
Awake, Start 호출 순서가 보장되지 않더라도 초기화 처리는 가능하겠지만, 어떤 GameObject 들의 초기화보다도 먼저 초기화 처리를 하고싶은 경우가 있을 수 있음.
이 때, [RuntimeInitializeOnLoadMethod] 어트리뷰트(Attribute)를 활용해서 특정 static 함수의 속성을 설정해서, 게임이나 앱 실행 후 가능한 빠른 시점에 호출되도록 핸들링 할 수 있음. 유니티 런타임을 시작하고 첫 번째 장면을 로드할 때 이 속성을 활용해서 콜백함수를 핸들링함.
설정들이 여럿 있는데, 대부분의 경우에는 BeforeSceneLoad 프로퍼티를 사용하면 첫 번째 신에 배치된 GameObject 들의 Awake 함수가 호출되기 전에 초기화를 수행할 수 있어서, 순서상으로 큰 문제는 없음.
public static class GameMain
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void UntiyMain()
{
// 다른 GameObject 들의 Awake(), Start() 함수보다 먼저 호출되는 함수.
// 여기서 필요한 초기화를 진행하면 된다.
}
}
RuntimeInitializeLoadType Properties 설명
위에 나열한 RuntimeInitializeLoadType의 모든 Properties 의 설명은 아래와 같음.
AfterSceneLoad
첫 번째 씬의 오브젝트가 메모리에 로드되고 Awake가 호출된 후에 호출
BeforeSceneLoad
첫 번째 씬의 오브젝트가 메모리에 로드되었지만 Awake가 호출되기 전에 호출
AfterAssembliesLoaded
모든 어셈블리가 로드되고 미리 로드된 에셋이 초기화될 때 호출. 이때 첫 번째 씬의 오브젝트는 아직 로드되지 않음.
BeforeSplashScreen
스플래시 화면이 표시되기 전에 호출되는 콜백. 이때 첫 번째 씬의 오브젝트는 아직 로드되지 않음.
SubsystemRegistration
런타임을 시작할 때 호출되는 콜백. 첫 번째 씬이 로드되기 전에 호출.
RuntimeInitializeOnLoadMethod 호출 순서
각 프로퍼티 콜백들이 어떤 순서로 호출되는지 호출 순서는 아래와 같음.
(다양한 로우 레벨 시스템(윈도우, 어셈블리, Gfx 등) 초기화)
1. SubsystemRegistration, AfterAssembliesLoaded
(입력 시스템 등 초기화)
2. BeforeSplashScreen
(첫 번째 씬 로드)
3. BeforeSceneLoad
(모든 오브젝트를 활성화. MonoBehaviour의 Awake, OnEnable 호출)
4. AfterSceneLoad
(Start 호출)
아래는 더 자세한 호출 순서.
static Lifecycle() => Debug.Log(Prefix + "Static Constructor");
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void Subs() => Debug.Log(Prefix + "Subsystem Registration");
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] static void AfterAsm() => Debug.Log(Prefix + "AfterAssembliesLoaded");
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)] static void BeforeSlash() => Debug.Log(Prefix + "Before Splash");
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void BeforeScene() => Debug.Log(Prefix + "BeforeScene");
private void Awake() => Debug.Log(Prefix + "Awake");
private void OnEnable() => Debug.Log(Prefix + "OnEnable");
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] static void AfterScene() => Debug.Log(Prefix + "AfterSceneLoad");
[RuntimeInitializeOnLoadMethod] static void DefaultLog() => Debug.Log(Prefix + "RuntimeInit Default");
void Start() => Debug.Log("Start");
참조 : https://docs.unity3d.com/ScriptReference/RuntimeInitializeOnLoadMethodAttribute.html
참조 : https://gist.github.com/hybridherbst/36ae70b6520981c8edc7b478423fae5e
게임 개발에 필수적인 내용을 담는 명서들을 소개합니다.
<유니티 교과서 개정6판>(유니티 최신 버전)
https://link.coupang.com/a/be3P0t
<대마왕의 유니티 URP 셰이더 그래프 스타트업>
https://link.coupang.com/a/bs8qyC
<리얼-타임 렌더링(REAL-TIME RENDERING) 4/e>
https://link.coupang.com/a/8VWas
<이득우의 게임 수학:39가지 예제로 배운다! 메타버스를 구성하는 게임 수학의 모든 것>
https://link.coupang.com/a/9BqLd
유니티 에셋 스토어 링크
https://assetstore.unity.com?aid=1011lvz7h
(링크를 통해 도서/에셋 구입시 일정액의 수수료를 지급받습니다.)