Unity에서 Play 버튼을 누르면 게임이 바로 실행되는 것처럼 보입니다.
하지만 내부에서는 여러 초기화 작업이 실행됩니다.
그중 하나가 Domain Reload입니다.
Domain Reload는 static 변수와 이벤트 상태를 초기화하는 역할을 합니다.
프로젝트가 커지면 이 과정도 시간이 걸릴 수 있습니다.
그래서 Unity에서는 Domain Reload를 끌 수 있습니다.
문제는 끈 순간부터 static 상태를 직접 관리해야 한다는 점입니다.
핵심 요약
- Domain Reload는 static 상태를 초기화합니다.
- 끄면 Play Mode 진입 시간이 줄어들 수 있습니다.
- 대신 static 값이 이전 Play 상태를 유지할 수 있습니다.
- SubsystemRegistration으로 static 값을 직접 초기화할 수 있습니다.
- static 이벤트도 중복 등록을 주의해야 합니다.
목표
Domain Reload를 껐을 때 static 값이 왜 남는지 확인합니다.
그리고 안전하게 초기화하는 방법을 알아봅니다.
결과물
최종적으로 다음 패턴을 사용합니다.
[RuntimeInitializeOnLoadMethod(
RuntimeInitializeLoadType.SubsystemRegistration)]
static void ResetStaticData()
{
playCount = 0;
}
Domain Reload를 꺼도 Play Mode마다 static 값을 초기화할 수 있습니다.
결과물로 얻을 수 있는 기대
Play Mode 진입 시간을 줄이면서 static 상태를 안정적으로 관리할 수 있습니다.
Domain Reload를 껐을 때 발생하는 이상한 Editor 버그도 줄일 수 있습니다.
1. 어떻게 끄고 켜지?
Enter Play Mode Settings 옵션
Unity 6에서는 Project Settings > Editor > Enter Play Mode Settings에서 동작을 선택할 수 있습니다.
이미지처럼 4가지 옵션이 있습니다.
옵션의미
| Reload Domain and Scene |
Domain과 Scene을 모두 다시 로드합니다. 가장 일반적인 초기화 방식입니다. |
| Reload Scene only |
Scene만 다시 로드합니다. static 상태는 유지될 수 있습니다. |
| Reload Domain only |
Domain만 다시 로드합니다. Scene 상태는 유지합니다. |
| Do not reload Domain or Scene |
둘 다 다시 로드하지 않습니다. Play Mode 진입은 빠르지만 직접 상태를 관리해야 합니다. |
2. Domain Reload란?
Domain Reload는 Unity가 스크립팅 상태를 다시 초기화하는 과정입니다.
기본적인 Play Mode에서는 static 변수도 초기화합니다.
예를 들어 다음 코드가 있다고 가정하겠습니다.
public static int PlayCount = 0;
게임에서 값을 변경합니다.
PlayCount = 10;
Play Mode를 종료하고 다시 실행합니다.
Domain Reload가 동작하면 다시 초기값으로 돌아갑니다.
첫 번째 Play
PlayCount = 0
값 변경
PlayCount = 10
Stop
두 번째 Play
PlayCount = 0
개발자가 별도 초기화 코드를 작성하지 않아도 됩니다.
3. Domain Reload를 끄면 어떻게 될까?
Domain Reload를 끄면 Play Mode 진입 시간을 줄일 수 있습니다.
하지만 static 값이 자동으로 초기화되지 않습니다.
간단한 테스트 코드를 만들어 보겠습니다.
using UnityEngine;
public class DomainReloadTest : MonoBehaviour
{
private static int playCount;
private void Start()
{
playCount++;
Debug.Log($"Play Count : {playCount}");
}
}
Domain Reload가 동작하면 매번 다음과 같이 출력됩니다.
Play Count : 1
하지만 Domain Reload를 끄면 값이 누적될 수 있습니다.
첫 번째 Play
Play Count : 1
두 번째 Play
Play Count : 2
세 번째 Play
Play Count : 3
playCount가 이전 값을 유지하기 때문입니다.
버그가 아니라 정상적인 동작입니다.
4. static 값을 직접 초기화하기
이 문제는 RuntimeInitializeOnLoadMethod로 해결할 수 있습니다.
using UnityEngine;
public class DomainReloadTest : MonoBehaviour
{
private static int playCount;
[RuntimeInitializeOnLoadMethod(
RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetStaticData()
{
playCount = 0;
}
private void Start()
{
playCount++;
Debug.Log($"Play Count : {playCount}");
}
}
이제 Domain Reload를 꺼도 결과는 같습니다.
첫 번째 Play
Play Count : 1
두 번째 Play
Play Count : 1
세 번째 Play
Play Count : 1
매번 Runtime 시작 시 직접 초기화하기 때문입니다.
5. 왜 SubsystemRegistration을 사용할까?
RuntimeInitializeOnLoadMethod에는 실행 시점을 지정할 수 있습니다.
이번에는 다음 값을 사용했습니다.
RuntimeInitializeLoadType.SubsystemRegistration
이 시점은 Runtime 초기 과정에서 실행됩니다.
Scene의 Awake()보다 먼저 static 상태를 초기화하기에 적합합니다.
따라서 Domain Reload를 끈 프로젝트에서 자주 사용할 수 있습니다.
6. static 이벤트도 주의해야 한다
Domain Reload를 끄면 변수만 확인하면 안 됩니다.
static 이벤트 등록 상태도 남을 수 있습니다.
예를 들어 다음 코드가 있습니다.
Application.quitting += OnQuit;
Play Mode에 들어갈 때마다 등록하면 중복될 수 있습니다.
그러면 하나의 이벤트가 여러 번 호출됩니다.
안전하게 처리하려면 기존 등록을 먼저 제거합니다.
[RuntimeInitializeOnLoadMethod(
RuntimeInitializeLoadType.SubsystemRegistration)]
static void Initialize()
{
Application.quitting -= OnQuit;
Application.quitting += OnQuit;
}
핵심은 이 패턴입니다.
이벤트 -= 함수;
이벤트 += 함수;
기존 등록을 제거한 뒤 다시 등록합니다.
7. Domain Reload를 꺼도 될까?
꺼도 됩니다.
다만 다음 두 항목을 직접 관리해야 합니다.
확인 항목이유
| static 변수 |
이전 Play 값이 남을 수 있음 |
| static 이벤트 |
이벤트가 중복 등록될 수 있음 |
프로젝트가 작다면 Domain Reload를 그대로 사용해도 됩니다.
Play Mode 진입 시간이 부담스러워지면 비활성화를 검토하면 됩니다.
마무리
Domain Reload를 끄는 목적은 간단합니다.
Play Mode 진입 시간을 줄이는 것입니다.
하지만 Unity가 해주던 static 초기화도 함께 사라집니다.
따라서 static 상태를 직접 관리해야 합니다.
가장 먼저 기억할 코드는 다음입니다.
[RuntimeInitializeOnLoadMethod(
RuntimeInitializeLoadType.SubsystemRegistration)]
static void ResetStaticData()
{
// static 데이터 초기화
}
static 이벤트도 함께 확인해야 합니다.
Domain Reload를 끄기 전에 이 두 가지만 점검해도 많은 문제를 예방할 수 있습니다.