[Unity] UniTask로 씬 이동하기
![[Unity] UniTask로 씬 이동하기](/_next/image?url=https%3A%2F%2Fdata.develog.develrocket.com%2Fupload%2Fdevelog%2Fuser_1777093328305%2F1781529944310-7pysou%2F_____2026-06-15_222406.png&w=3840&q=75)
본문 로딩 중...
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
흐름
버튼 클릭
│
▼
① 페이드 아웃 (화면 까매짐, 완료까지 대기) ─ 약 1초
│ ← 이 시점엔 아직 씬 A, 로드 시작 안 함
▼
③ 씬 B 비동기 로드 시작 (까만 화면 뒤에서)
│ progress 0.9 도달 + 최소시간 대기
▼
allowSceneActivation = true → 씬 A 내려가고 씬 B 활성화
│ ← 화면은 여전히 까맣게 덮여 있음
▼
④ 페이드 인 (씬 B가 서서히 드러남)
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.InputSystem;
public class FadeController : MonoBehaviour
{
public CanvasGroup fadeCanvasGroup;
public float fadeDuration = 1f;
private static FadeController instance;
private void Awake()
{
if (instance != null && instance != this)
{
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
fadeCanvasGroup.alpha = 0f;
}
private void OnDestroy()
{
if (instance == this)
{
instance = null;
}
}
public async UniTask FadeOut(float duration = -1f)
{
if (duration < 0f)
duration = fadeDuration;
await FadeAsync(fadeCanvasGroup, 0f, 1f, duration);
}
public async UniTask FadeIn(float duration = -1f)
{
if (duration < 0f)
duration = fadeDuration;
await FadeAsync(fadeCanvasGroup, 1f, 0f, duration);
}
private async UniTask FadeAsync(CanvasGroup canvasGroup, float from, float to, float duration)
{
canvasGroup.alpha = from;
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = elapsed / duration;
canvasGroup.alpha = Mathf.Lerp(from, to, t);
await UniTask.Yield();
}
canvasGroup.alpha = to;
}
}
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = elapsed / duration;
canvasGroup.alpha = Mathf.Lerp(from, to, t);
await UniTask.Yield();
}
여기서 await UniTask.Yield()는 코루틴의 yield return null 과 같다
using System;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneLoadController : MonoBehaviour
{
public Button loadSceneButton;
public Slider progressSlider;
public TMP_Text progressText;
public FadeController fadeController;
public string targetSceneName;
public float minimumLoadTime = 2f;
private bool isLoading = false;
private void Start()
{
loadSceneButton.onClick.AddListener(OnLoadSceneClicked);
fadeController = FindFirstObjectByType<FadeController>();
gameObject.SetActive(false);
}
private void OnLoadSceneClicked()
{
OnLoadSceneWithFadeAsync().Forget();
}
private async UniTask OnLoadSceneWithFadeAsync()
{
progressSlider.value = 0f;
progressText.text = "로딩 중... 0%";
await fadeController.FadeOut();
gameObject.SetActive(true);
isLoading = true;
loadSceneButton.interactable = false;
await LoadSceneAsync();
await fadeController.FadeIn();
isLoading = false;
// loadSceneButton.interactable = true;
// gameObject.SetActive(false);
}
private async UniTask LoadSceneAsync()
{
var progress = Progress.Create<float>(p =>
{
progressSlider.value = p;
progressText.text = $"로딩 중... {(int)(p * 100)}%";
Debug.Log($"로딩 중... {(int)(p * 100)}%");
});
var asyncOp = SceneManager.LoadSceneAsync(targetSceneName);
asyncOp.allowSceneActivation = false; // 얘를 true로 하면 씬이 바로 넘어감 나중에 바꿀때 true 전환
float startTime = Time.time;
while (asyncOp.progress < 0.9f)
{
progress.Report(Mathf.Clamp01(asyncOp.progress / 0.9f));
await UniTask.Yield();
}
float elapsed = Time.time - startTime;
if (elapsed < minimumLoadTime)
{
await UniTask.Delay(TimeSpan.FromSeconds(minimumLoadTime - elapsed));
}
progress.Report(1.0f);
asyncOp.allowSceneActivation = true;
await asyncOp.ToUniTask();
}
}
allowSceneActivation = false일 때 asyncOp.progress는 0.9에서 멈춰서 나머지 0.1은 활성화에 쓰이는 구간이라 false면 도달을 안함


잘 보이진 않지만 씬 A에서 페이드 아웃 되면서 로딩창이 뜨고 씬 B로 이동하는 것을 볼 수 있다.
SerializeReference
![[Unity] 튜토리얼 설계](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1787322579554-zopplu/_____2026-08-21_232731.png)
튜토리얼 설계
![[Unity] Event Trigger Component](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1786976296699-a3tu75/_____2026-08-17_231353.png)
Unity Event Trigger 컴포넌트
![[Unity] 튜토리얼 설계](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1787322579554-zopplu/_____2026-08-21_232731.png)
![[Unity] Event Trigger Component](https://data.develog.develrocket.com/upload/develog/user_1777093328305/1786976296699-a3tu75/_____2026-08-17_231353.png)