[Unity] 로딩화면 구현하기_일정 구간은 설정한 시간에 따라, 그 뒤는 실제 진행률로

지즈·2025년 1월 12일
0

Unity

목록 보기
6/17

유니티의 로딩 화면을 제작 중에 로딩 진행률을 나타내는 코드를 구현해봤다. 유니티 UI - Slider를 이용하여 현재 로딩 진행률을 시각적으로 표현하려고 했다.

구현 의도 설명

구현하고자 했던 목표는 다음과 같다.

  1. 일정 구간 동안은 실제로 얼마나 로딩됐는지와 상관없이 일정한 속도로 증가하게 한다. 로딩 화면이 너무 빠르게 진행되는 걸 방지하기 위해서다.
  2. 위 구간이 지나면, 실제 얼마나 로딩됐는지에 따라 진행률을 나타냈다.

로딩 화면에 진행률 구현하기 스크립트

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class NextSceneManager : MonoBehaviour
{

    [SerializeField]
    private GameObject pannelLoading; // 로딩 화면 대신 패널을 이용했다
    [SerializeField]
    private Slider sliderProgress; // 로딩 상태를 나타낼 슬라이더
    [SerializeField]
    private float loadingDelayTime; // 다음 씬 전환까지 지연을 위한 시간  

    private float currentTick;
    private float moveTick;
    

    private void Start()
    {
        currentTick = 0f;
        moveTick = 0.0003f;
    }

    public void StartLoadingCoroutine(string sceneName)
    {
    	// 코루틴을 호출한다
        StartCoroutine(LoadingProgress(sceneName));
    }
    

    // 로딩 작업 완료 후 다음 씬으로 이동하는 코루틴
    public IEnumerator LoadingProgress(string sceneName)
    {
        // 비동기 로드 시작 
        AsyncOperation op = SceneManager.LoadSceneAsync(sceneName);

        // 해당 작업 중 다른 씬으로 바로 전환되지 않도록 한다
        op.allowSceneActivation = false;
		
        // 1번 구간에서의 증가량을 구한다 : Start()에 위치하는 게 더 적절하지만 가독성을 위해....
        float toLoadingTime = (Time.deltaTime / loadingDelayTime);

        // 로딩 진행률 업데이트
        while (!op.isDone)
        {
            // 슬라이더의 70% 까지는 toLoadingTime을 이용하여 업데이트
            if (sliderProgress.value < 0.7)
            {
                currentTick += toLoadingTime;
                sliderProgress.value = currentTick;
            }
            // 슬라이더의 70% 도달했는데, 실제 진행률이 70% 이상일 때 슬라이더 최대 0.03씩 이동
            // 실제 진행률이 70% 미만이라면, 70%에서 대기하게 된다
            else if (op.progress > sliderProgress.value)
            {
                sliderProgress.value = Mathf.MoveTowards(sliderProgress.value, op.progress, moveTick);
            }

            // 비동기 로딩 작업이 완료된 경우
            // op.progress는 ture가 되기 전까지 0.9가 최댓값이다.
            else if (op.progress >= 0.9f)
            {
		        // 0.9에서 바로 1.0으로 이동하는 걸 막기 위해 moveTick을 더해 자연스럽게 증가한다.
                while (sliderProgress.value < 0.99f) sliderProgress.value += moveTick;
                op.allowSceneActivation = true;
            }
            yield return null;
        }
    }
}

주의해야 할 점

AsyncOperation.allowSceneActivation 속성을 false로 설정하면, progress는 0.0에서 0.9까지 진행된다. 씬 로딩이 완료되었더라도, allowSceneActivationfalse일 때는 씬을 활성화하지 않기 때문에 progress는 0.9에서 멈춘다. 이 때, 최댓값이 0.9이기 때문에 작업의 완료 조건 설정 시 1.0으로 생각해선 안 된다.

또, 슬라이더의 증가율을 부드럽게 하겠다고 이 코드에서 MoveTowards() 대신 Lerp() 함수를 사용해선 안 된다. Lerp()는 절대 목표치에 도달하지 않고 무한히 가까워지지만, MoveTowards()는 반드시 목표치에 도달하기 때문에 이 메소드를 사용했다.

profile
클라이언트 개발자가 되는 그 날까지 킵 고잉

0개의 댓글