Unity

[Unity Tip] RuntimeInitializeOnLoadMethod Attribute

성엽이 2022. 12. 14. 11:10

https://mentum.tistory.com/610

 

gereric singleton의 RuntimeInitializeOnLoadMethod 실행문제

요즘 개발할때 유니티의 enter play mode 를 적극 활용해보려고하고 있다. https://blog.unity.com/kr/technology/enter-play-mode-faster-in-unity-2019-3 더욱 빨라진 Unity 2019.3 버전 Enter Play Mode | Unity Blog Play Mode(플레이

mentum.tistory.com

 

https://blog.unity.com/kr/technology/enter-play-mode-faster-in-unity-2019-3

 

더욱 빨라진 Unity 2019.3 버전 Enter Play Mode | Unity Blog

Play Mode(플레이 모드)를 이용하면 Unity를 더욱 다채롭게 활용할 수 있습니다. 프로젝트가 복잡해질수록 Play Mode를 시작하는 데 걸리는 시간이 길어지며, Play Mode를 빠르게 시작하고 종료할 수 있어

blog.unity.com

 

https://docs.unity3d.com/kr/2021.2/Manual/ConfigurableEnterPlayMode.html

 

설정 가능한 플레이 모드 시작 - Unity 매뉴얼

플레이 모드는 Unity의 핵심 기능 중 하나입니다. 이 모드를 사용하면 툴바의 Play 버튼을 통해 에디터 내에서 프로젝트를 직접 실행할 수 있습니다. 플레이 모드를 시작하면 프로젝트가 빌드에서

docs.unity3d.com

 

https://docs.unity3d.com/kr/2021.2/Manual/DomainReloading.html

 

도메인 재로드 - Unity 매뉴얼

도메인 재로드(기본적으로 활성화됨)를 수행하면 스크립팅 상태가 초기화됩니다. 또한 완전히 새로운 스크립팅 상태를 제공하며, 플레이 모드를 시작할 때마다 정적 필드와 등록된 핸들러가 전

docs.unity3d.com

 


RuntimeInitializeOnLoadMethod Attribute 는 보통 초기화를 위해서 사용한다. 그래서 디버깅용으로 많이 사용한다.

로그인을 실행하는씬에서 먼저한다던가, 처음씬으로 돌아가서 실행하지않아도 처음씬으로 간다던가

 

GameObject 에 할당을 하지 않아도 처음 한번만 사용되며,

RuntimeInitializeOnLoadMethod  뒤에 같은 조건이 붙으면 공식페이지에서 순서는 보장되지 않는다지만 메소드의 알파벳 순서에 따라 순차적으로 호출된다.

 

using UnityEngine;
using UnityEngine.SceneManagement;

public class RuntimeInitialize : MonoBehaviour
{
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void FirstLoad()
    {
#if UNITY_EDITOR
        if (SceneManager.GetActiveScene().name.CompareTo("Login") != 0)
            SceneManager.LoadScene("Login");
#endif
    }
    
    [RuntimeInitializeOnLoadMethod]
    static void A()
    {
        Debug.Log("AAA");
    }

    [RuntimeInitializeOnLoadMethod]
    static void B()
    {
        Debug.Log("BBB");
    }
}

//출력
AAA
BBB

 

 - 실행순서

 

1. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]

2. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]

3. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]

4. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]

5. Awake()

6. [RuntimeInitializeOnLoadMethod]

7. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad )]

8. Start()

 

- 문제점

 

도메인이 Reload 되지않기 때문에 static 변수들이 초기화 되지 않는다는 것.

 

 

아무런 수정이나 삭제없이 다시 시작할 경우 static 변수는 이전실행 값 그대로 메모리에 남아있다.

 

물론 수정이나 삭제를 한번 해주면 Reloading 이 된다.

 

하지만 확실히 보장을 해주기 위해서 사용할수 있는게 RuntimeInitializeOnLoadMethod Attribute 이다

 

 

static 하면 싱글톤과 연관이 많은데 singleton 은 generic class 사용이 많다.

 

하지만 RuntimeInitializeOnLoadMethodgeneric class 에서 동작하지 않는다.

 

'제네릭은 런타임에 바인딩이라 호출 시점의 문제인 듯 하다.' 라고 위에 mentum 님 블로그에 적혀있다.

 

근데 정말 정확히는 모르겠다. 나도 해보니 안된다.

 

 

 

# Domain Reload, Scene Reload 에 대해서는 위에 공식홈페이지 설명을 보면되겠다.