Chapter 12-9. 기타 : 로딩화면 만들기 (AsyncOperation.progress)

Date:     Updated:

카테고리:

태그:

로딩 화면 만들기

image

강의에서 진행한 부분은 아니였지만 로딩화면 만들 수 있다고 언급하셔서 한번 만들어봤다.

🚀 로딩 씬

image

  • 로딩 화면으로 쓰기 위해 “GameLoad” 라는 씬을 새로 만들었다. (Build Setting 에 추가해주었다.)
  • 초록 패널에 슬라이더를 사용한 모습
    • 로딩 진행도를 이 슬라이더로 표시할 것이다.


🚀 스크립트

📜Title

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Title : MonoBehaviour
{
    public string startSceneName = "GameStage";
    public string loadSceneName = "GameLoad";

    public void ClickStart()
    {
        Debug.Log("로딩");
        SceneManager.LoadScene(startSceneName);
    }

    public void ClickLoad()
    {
        Debug.Log("로드");
        SceneManager.LoadScene(loadSceneName);
    }

    public void ClickExit()
    {
        Debug.Log("게임 종료");
        Application.Quit();
    }
}

기존 타이틀 메뉴를 좀 수정해주었다. 원랜 이게 싱글톤이였고 여기서 게임 씬을 불러들였는데 그냥 버튼 이벤트에 등록하는 정도의 함수만 만들어주었다. 로드 버튼을 누르면 “GameLoad” 로딩 씬을 불러오도록 한다.


📜LoadManager

“GameLoad” 씬의 Canvas에 붙였다.

이 로딩씬에서 이 스크립트를 통해 게임 씬을 불러올 것이다.

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

public class LoadManager : MonoBehaviour
{
    public string sceneName = "GameStage";
    public Slider slider; // 여기에 슬라이더 오브젝트 할당
    private AsyncOperation operation;

    private SaveAndLoad theSaveAndLoad;

    public static LoadManager instance;

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
            Destroy(gameObject);
    }

    void Start()
    {
        StartCoroutine(LoadCoroutine());
    }

    IEnumerator LoadCoroutine()
    {
        operation = SceneManager.LoadSceneAsync(sceneName);
        operation.allowSceneActivation = false;

        float timer = 0f;
        while (!operation.isDone)
        {
            yield return null;

            timer += Time.deltaTime;
            if (operation.progress < 0.9f)
            {
                slider.value = Mathf.Lerp(operation.progress, 1f, timer);
                if (slider.value >= operation.progress)
                    timer = 0f;
            }
            else  
            {
                slider.value = Mathf.Lerp(slider.value, 1f, timer); 
                if (slider.value >= 0.99f)
                    operation.allowSceneActivation = true;
            }
        }

        theSaveAndLoad = FindObjectOfType<SaveAndLoad>(); // 다음 씬의 📜SaveAndLoad
        theSaveAndLoad.LoadData();
        gameObject.SetActive(false);
    }
}

이번에 알게된게 있다. operation.progress최대값이 0.9f 인 것 같다. 그리고 로딩 과정이 그리 무겁지 않다면 순식간에 operation.progress 값은 1 프레임만에 0.9f 값이 되었고 그리고 그 이후부턴 0.9 를 유지한 것을 로그 출력으로 확인할 수 있었다.

  • 씬은 슬라이더 값이 99% 이상일 떄 불러올 것이기 때문에 미리 operation.allowSceneActivation = false; 로 해둔다.
  • 씬 전환은 1 프레임만에 이루어졌다. 그때 그때 경우에 따라 다르겠지만 이렇게 씬 전환이 눈깜짝할 새에 이루어지는 경우도 있고 이럴 땐 바로 operation.progress 값이 0.9 가 되버렸다.
    • 그래서 씬 전환이 빨리 이루어졌다면 while 문 내의 if 는 실행 안되고 바로 else 만 실행 될지도 모른다.
      • operation.progress는 0.9 가 최대값인 것을 확인했다. 그냥 씬 전환이 완료되면 0.9 값이 되나보다.
      • 그래도 슬라이더를 90%인 상태에서 멈출 수는 없으니, operation.progress가 0.9 이상일 때부인 else문에서는 슬라이더 값이 100%가 될때까지 timer로 보간해가며 부드럽게 100% 를 향해 슬라이더 값을 올린다.
      • Lerp 보간을 사용하면 딱 떨어지게 1f 가 되기는 힘들다. 그래서 슬라이더 값이 0.99f 만 넘게 되면 바로 로딩하는 씬을 활성화시키도록 하였따. 이때 비로소 씬을 활성화한다. operation.allowSceneActivation = true;
  • 이 스크립트는 씬 전환이 완료되도 게임 씬에서 저장했던 내용 그대로를 불러오는 작업을 해야 하기 때문에 (즉, 📜SaveAndLoad의 LoadData 함수를 실행해야 하기 때문에) 싱글톤으로 만들었다. 씬이 전환되도 파괴되지 않고 전환된 게임 씬에서 theSaveAndLoad.LoadData();를 실행해야 함.


🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

Unity Lesson 3 카테고리 내 다른 글 보러가기

댓글 남기기