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

Play Mode(플레이 모드)를 이용하면 Unity를 더욱 다채롭게 활용할 수 있습니다. 프로젝트가 복잡해질수록 Play Mode를 시작하는 데 걸리는 시간이 길어지며, Play Mode를 빠르게 시작하고 종료할 수 있어야 변경 사항을 신속하게 적용하고 테스트할 수 있습니다. 이번 Unity 2019.3 베타에서는 이 기능을 구현한 Configurable Enter Play Mode(설정 가능한 플레이 모드 진입)를 실험적으로 도입했습니다.
에디터에서 Play Mode에 진입하면 Unity가 스크립팅 상태(도메인 리로드)를 재설정하고 씬을 리로드합니다. 이 과정에는 일정 시간이 소요되며, 프로젝트가 복잡할수록 Play Mode에서 새로운 변경 사항을 테스트하기 위해 대기하는 시간이 길어집니다. 하지만 Unity 2019.3 베타 버전부터는 '도메인 리로드' 및 '씬 리로드' 동작을 각각 또는 동시에 비활성화할 수 있는 옵션이 제공됩니다.
자체 테스트 결과에 따르면, 이 옵션으로 인해 프로젝트에 따라 대기 시간이 최소 50%에서 최대 90%까지 단축되었습니다.

Edit > Project Settings > Editor에서 Enter Play Mode 옵션을 클릭하면 Reload Domain 및 Reload Scene 옵션이 활성화됩니다. 기술 자료에서 Play Mode 설정 방법에 대해 더 자세한 내용을 확인하실 수 있습니다.

이 옵션을 사용하면 코드 변경 사항이 없는 경우에 Enter Play Mode 과정에서 도메인 또는 씬이 리로드되지 않도록 비활성화할 수 있습니다. Play Mode에 진입하기 전에 게임 상태를 재설정하려면 API와 콜백을 통해 이 기능을 사용할 수 있습니다.
아래 다이어그램은 Reload Domain 및 Reload Scene을 비활성화하기 전과 후의 Enter Play Mode 프로세스를 보여줍니다.

Reload Domain을 비활성화한 후에는 Play Mode에 진입했을 때 스크립팅 상태가 올바르게 재설정되도록 반드시 스크립트의 정적 필드 및 정적 이벤트 핸들러를 조정해야 합니다.
다음 코드 예시에는 플레이어가 점프 버튼을 누르는 횟수를 집계하는 카운터가 있습니다. Reload Domain이 활성화된 경우, 이 카운터는 Play Mode에 진입할 때 자동으로 0으로 재설정됩니다. Reload Domain을 비활성화하면 카운터가 재설정되지 않으며 Play Mode 진입 및 종료 시의 값을 유지합니다. 즉, 이전 실행 시 카운터 값이 변경되었다면 에디터에서 프로젝트를 다시 실행했을 때 0으로 표시되지 않을 수 있습니다.
public class StaticCounterExample : MonoBehaviour
{
//this counter will not reset to zero when Domain Reloading is disabled
static int counter = 0;
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Jump"))
{
counter++;
Debug.Log("Counter: " + counter);
}
}
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] 속성을 사용하고, 값을 명시적으로 재설정하여 Reload Domain이 비활성화된 상태에서도 카운터가 올바르게 재설정되도록 하세요. 예:
using UnityEngine;
public class StaticCounterExampleFixed : MonoBehaviour
{
static int counter = 0;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Init()
{
Debug.Log("Counter reset.");
counter = 0;
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Jump"))
{
counter++;
Debug.Log("Counter: " + counter);
}
}
}
Reload Domain을 비활성화한 경우 Play Mode를 종료해도 Unity가 정적 이벤트 핸들러로부터 메서드를 등록 해제하지 않습니다. 따라서 정적 이벤트 핸들러에 메서드를 등록하는 코드가 있는 경우 복잡한 문제로 이어질 수 있습니다. 예를 들어, 에디터에서 프로젝트를 처음으로 플레이하는 경우 메서드가 통상적으로 등록됩니다. 하지만 프로젝트를 다시 플레이하는 순간 해당 메서드는 첫 번째에 이어 두 번째로 등록되어 이벤트 발생 시 두 번 호출됩니다.
다음 코드는 정적 이벤트 핸들러 Application.quitting에 메서드를 등록합니다.
using UnityEngine;
public class StaticEventExample : MonoBehaviour
{
void Start()
{
Debug.Log("Registering quit function");
Application.quitting += Quit;
}
static void Quit()
{
Debug.Log("Quitting!");
}
}
Reload Domain이 비활성화된 경우, 위 예시에서는 Play Mode에 진입할 때마다 Quit 메서드를 다시 추가하며, Play Mode를 종료할 때마다 추가적인 'Quitting' 메시지가 표시됩니다.
[RuntimeInitializeOnLoadMethod] 속성을 사용하고 메서드를 확실히 등록 취소하여 두 번 추가되지 않도록 합니다.
using UnityEngine;
public class StaticEventExampleFixed : MonoBehaviour
{
[RuntimeInitializeOnLoadMethod]
static void RunOnStart()
{
Debug.Log("Unregistering quit function");
Application.quitting -= Quit;
}
void Start()
{
Debug.Log("Registering quit function");
Application.quitting += Quit;
}
static void Quit()
{
Debug.Log("Quitting the Player");
}
}
Reload Domain이 비활성화되었을 때 스크립트가 올바르게 실행되도록 수정하는 방법은 유니티 기술 자료에서 보실 수 있습니다.
유니티는 인기 에셋 스토어 패키지에서 Reload Domain 및 Reload Scene 옵션을 비활성화할 수 있도록 지원하고자 합니다. 프로젝트에서 문제가 발생하면 에셋 패키지 퍼블리셔에게 알려주세요.
Play Mode에 진입하는 데 시간이 오래 걸리는 프로젝트의 경우, 이 기능을 통해 시간을 상당히 단축할 수 있습니다. Unity 2019.3 베타에 참여하여 새로운 기능을 직접 사용해보고 포럼에서 의견을 공유해 주세요! 현재 실험 단계에 있는 기능이므로 사용자의 필요에 따라 얼마든지 수정될 수 있습니다. 개발 중 발생한 문제들을 공유해주시기 바랍니다.
이 기능을 먼저 테스트해보고 소중한 피드백을 제공해주신 @Sini, @chrisk, @Peter77, @Baste님께 감사의 말씀을 전합니다.