본문 바로가기

프로그래밍/Unity

Unity SceneManager.sceneLoaded

Unity 코드 작성 중, 해당 Scene이 모두 로드되었을 경우 어떤 작업을 해줘야하는 일이 있어 관련 API를 찾아보았다.

 

UnityEngine.SceneManagement 네임 스페이스안의 SceneManager.sceneLoaded 이벤트에 자신의 이벤트를 추가해주면 된다.

 

다만 새로 알게 된 것은, MonoBehaviourOnEnable에서 해당 이벤트에 추가하는 경우에도 정상적으로 씬의 로드 이벤트 통지를 받을 수 있다는 것이다.

 

생각하기로는, SceneManager.sceneLoaded가 먼저 호출이 된 뒤, MonoBehaviour.OnEnable의 순서일 줄 알았는데,

오히려 그 반대로 해당 씬의 모든 오브젝트의 OnEnable을 호출 한 뒤 씬 로드 이벤트가 발생한다.

 

https://docs.unity3d.com/Manual/ExecutionOrder.html

 

Unity - Manual: Order of Execution for Event Functions

Understanding Automatic Memory Management Order of Execution for Event Functions Running a Unity script executes a number of event functions in a predetermined order. This page describes those event functions and explains how they fit into the execution se

docs.unity3d.com

유니티 공식 Event Function Execution 순서에는 나와있지 않은 것 같다.

그렇다면 대충 어느 시점에 이벤트가 호출되는 것인지 궁금해졌다.

OnEnable에 확실히 받을 수 있는 것은 알았기 때문에, 아래와 같이 테스트 해보았다.

 

using UnityEngine;
using UnityEngine.SceneManagement;

public sealed class SceneLoadOrderTester : MonoBehaviour
{
	private void Awake()
	{
		Debug.Log("Awake Called");
		SceneManager.sceneLoaded += StorySceneLoaded;
	}
    
	private void OnEnable()
	{
		Debug.Log("OnEnable Called");
	}
    
	private void Start()
	{
		Debug.Log("Start Called");
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= StorySceneLoaded;
	}

	private void StorySceneLoaded(Scene scene, LoadSceneMode mode)
	{
		Debug.Log("sceneLoaded Called");
		if (IsTargetScene(scene) == false)
		{
			return;
		}

		InitializeComponents();
	}
    
    ...
 }

 

결과는 위와 같다.

Awake -> OnEnable -> SceneManager.sceneLoaded -> Start의 순이다.