Chapter 12-9. 기타 : 로딩화면 만들기 (AsyncOperation.progress)
카테고리: Unity Lesson 3
태그: Unity Game Engine
로딩 화면 만들기
강의에서 진행한 부분은 아니였지만 로딩화면 만들 수 있다고 언급하셔서 한번 만들어봤다.
🚀 로딩 씬
- 로딩 화면으로 쓰기 위해 “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;
- 그래서 씬 전환이 빨리 이루어졌다면 while 문 내의 if 는 실행 안되고 바로 else 만 실행 될지도 모른다.
- 이 스크립트는 씬 전환이 완료되도 게임 씬에서 저장했던 내용 그대로를 불러오는 작업을 해야 하기 때문에 (즉, 📜SaveAndLoad의 LoadData 함수를 실행해야 하기 때문에) 싱글톤으로 만들었다. 씬이 전환되도 파괴되지 않고 전환된 게임 씬에서
theSaveAndLoad.LoadData();
를 실행해야 함.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기