https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html
씬 전환을 위해 사용하는 LoadScene의 내용
* 알아둬야 할 내용은
요 두 부분 정도 언데 Async를 사용해야 하는지랑 이건 몰랐던 것인데 Resources.UnloadUnusedAssets();가 자동 호출이 되는 것... 헐....(*이지만 사실 그리 중요한 건 아니구..)
Resources.UnloadUnusedAssets();의 내용은
https://docs.unity3d.com/ScriptReference/Resources.UnloadUnusedAssets.html
를 참고하면 됨 (* Resources.UnloadUnusedAssets()의 경우는 꼭 씬 전환시에만 사용할 게 아니라 간혹 메모리를 정리해야 할 상황이 올 수 있는데 이때도 사용한다.)
어쨌든 여기서 씬 전환이 Unity에서 내부적으로 어떻게 돌아가는지를 꼭 알아야 한다.
예로 a, b씬이 있다 가정할 때 a씬에서 b씬으로 전환할 때 Unity에서 메모리 처리 과정은
이미 a씬에 대한 메모리가 올라가 있을 것이고 b씬이 로드되게 되는데 이때 a씬의 메모리를 내리고 b씬이 로드되면서 메모리가 올라오는 것이 아니라 a씬의 메모리가 올라와 있는 상태에서 b씬의 메모리가 같이 올라오고 그 뒤에 b씬의 로드가 끝나면 a씬을 제거하면서 a씬이 할당하고 있던 메모리가 내려가게 된다.
그렇기에 각 씬이 차지하는 메모리가 많을 경우 혹은 동시에 씬이 올라왔을 때 순간 메모리가 많아지는 경우를 대비하여 씬 전환 시 빈 씬이나 혹은 로드 씬을 사용하는 것이다.
즉, 빈 씬인 n이 있고 a씬에서 b씬으로 로드한다 가정하면
a(now) -> n(load) -> a(remove) -> b(load) -> n(remove)의 느낌으로 가는 게 메모리 측면에서 과부하를 대비할 수 있다.
본인의 경우
요런 식으로 중간에 거쳐가는 씬을 하나 두고
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class NextScene : MonoBehaviour
{
[SerializeField] TMP_Text _TMP_progress = null;
private void Start()
{
AD.Managers.SceneM.GoScene();
}
private void Update()
{
this._TMP_progress.text = $"{AD.Managers.SceneM.Progress * 100}%";
}
}
이렇게 NextScene의 로드가 끝난 뒤에 SceneM의 GoScene메서드를 통해 씬 전환을 하는데 SceneM의 경우
using System.Collections;
using UnityEngine;
namespace AD
{
public class SceneManager : MonoBehaviour
{
AD.Define.Scenes _scene;
Coroutine _co_GoScene = null;
float progress = 0f;
public float Progress { get { return progress; } }
public void NextScene(AD.Define.Scenes scene)
{
this._scene = scene;
UnityEngine.SceneManagement.SceneManager.LoadScene(AD.Define.Scenes.NextScene.ToString());
}
public void GoScene()
{
_co_GoScene = StartCoroutine(Co_GoScene());
}
IEnumerator Co_GoScene()
{
AsyncOperation ao = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(this._scene.ToString());
while (!ao.isDone)
{
AD.Debug.Log("SceneManager", $"{ao.progress} - progress");
this.progress = ao.progress;
yield return null;
}
if (_co_GoScene != null)
{
StopCoroutine(_co_GoScene);
_co_GoScene = null;
Resources.UnloadUnusedAssets();
}
}
}
}
이런 식으로 가고 싶은 씬을 받아둔 뒤 NextScene에서 GoScene()을 호출하여 전환하는 식으로 진행한다.
Load가 얼마나 됐는지를 확인하기 위해 코드를 이렇게 하고 있긴 한데 이러면 Async의 의미가 없는 것 같기에... 음 지금 보니 개선이 필요.. 하다....
'Unity > Tips' 카테고리의 다른 글
Unity RuntimeInitializeOnLoadMethod을 이용한 초기 세팅 (2) | 2022.07.26 |
---|---|
Unity GitHub 사용 시 .gitignore 만들 때 (0) | 2022.06.20 |
Unity 인터넷 연결 간단히 확인 (1) | 2022.04.11 |
Unity 구글 Play 게임즈 서비스 설정(구글 로그인 요즘 느낌으로 다가) (6) | 2022.04.03 |
Unity Android 빌드 후 국가별(언어별) 앱 이름 대응 (2) | 2022.03.16 |