유니티에서 게임을 만들 땐, 여러 방법이 있겠지만, 씬을 여러개를 두고 전환해야되는 일이 생기기 마련이다.
보통 처음 유니티를 배울 땐, 씬 로딩을 UnityEngine.SceneManagement에 포함되어있는 SceneManager.LoadScene을 사용해 구현하곤 한다.
나쁜 방법은 아니지만, 씬에 로딩해야 할 데이터가 많거나 한다면, 씬 전환 간 유저는 멈춘 화면에서 대기를 해야할 수 있다.
이러한 점을 보완하고자, 비동기적으로 씬을 호출하는 작업을 하면 좋다.
비동기란 무엇인가?
비동기는 말 그대로 동기화되지 않았다는것이다.
예를 들어서 유니티에서는 다음과 같은 라이프사이클이 있다.
엄청 긴데 우리는 간단하게 Awake-> Start-> Update만 알고 있으면 얼추 될것같다.
유니티에서는 다음과 같이 라이프사이클이 있고, 모든 객체는 이러한 라이프 사이클을 따르게 된다.
그래서 우리는 유니티에서 테스트하기 위해 play를 누르면 라이프사이클을 따라 프로그램이 실행되게 된다.
모든 객체는 라이프사이클을 따르게 되어 있고, 위의 라이프사이클에 '동기화'되어서 함께 실행된다.
어떤 프로그램이던, 코드는 순차적으로 실행되기 때문에 뒤에 선언된 함수는 앞에 선언된 함수보다 늦게 실행되기 마련이다. 이렇게 모두 순차적으로 실행되는것을 동기라고 보면 된다.
비동기는 위와 반대로 순차적으로 진행되는 사이클에서 가지를 하나 뻗는다고 생각하면 된다.
이렇게 뻗어난 가지는 스스로 새로운 사이클을 갖게 된다.
지금 동기에서는 1,2,3,4번 함수가 순차적으로 실행되지만, 3번함수는 사실 1번함수가 끝난 직후에 호출되어야 한다고 가정해보자. (최적일 때 t4에서 실행해야되지만 t7에서 실행되도 오류가 나지 않는다고 가정하자.)
이럴때, 비동기적으로 3번 함수를 호출하면 1,2,4번함수의 사이클에서 3번함수만 따로 실행할 수 있게 되는것이다.
따라서, 우리가 다음씬을 위한 데이터를 호출하거나, 비동기적으로 이뤄져야하는 작업이 필요할때 꼭 필요한기술이 비동기이다.
비동기 씬 호출
그래서 비동기적으로 씬을 어떻게 호출하는건가?
진짜 간단하다 그냥 LoadSceneAsync를 쓰면 된다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadSceneManager : MonoBehaviour
{
public void LoadScene(string name){
SceneManager.LoadSceneAsync(name);
}
}
진짜 간단하게 코드를 작성했다.
그리고, 씬을 로딩할 땐 Build Setting에서 다음과 같이 로딩 할 씬을 추가해줘야한다. 씬을 드래그해서 넣어주면 된다.
이렇게 해두고, 버튼을 Loadingscene에 생성해 눌러보면 엄청 빠르게 씬이 로딩되는것을 볼 수 있다.
지금으로써는 비동기라고 하기에도 뭐하다(라이프사이클이 너무 짧아서)
이제 본격적으로 비동기 코드를 작성해보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadSceneManager : MonoBehaviour
{
float time = 0;
public void LoadScene(string name){
StartCoroutine(LoadingAsync(name));
}
IEnumerator LoadingAsync(string name){
AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(name);
asyncOperation.allowSceneActivation = false; //로딩이 완료되는대로 씬을 활성화할것인지
while(!asyncOperation.isDone){ //isDone는 로딩이 완료되었는지 확인하는 변수
time += Time.deltaTime; //시간을 더해줌
print(asyncOperation.progress); //로딩이 얼마나 완료되었는지 0~1의 값으로 보여줌
//이건 로딩이 너무 빨라서 작성한거라, 무거운 씬 로딩할땐 시간 체크하는 부분은
//생략해도 무방하다!
if(time > 3){ //3초 기다림(변동가능)
asyncOperation.allowSceneActivation = true; //씬 활성화
}
yield return null;
}
}
}
비동기를 호출하는 코드는 보통 코루틴을 사용해 구현한다.
함수 | Type | 설명 |
allowSceneActivation | bool | 씬 로딩이 완료되었을 때, 바로 화면을 전환할건지. (false면 로딩이 완료되어도 바로 전환 하지 않음, 나중에 true로 변할경우 씬이 전환됨.) |
isDone | bool | 씬 전환이 완료되었는지 확인하는 변수 |
progress | float | 씬이 현재 얼마나 로딩되었는지 정규화된 값으로 알려줌 (0.0~ 1.0) |
실행하면 다음과 같이 실행된다.
여전히 씬이 무겁지 않아서 순식간에 로딩이 되지만, 그래도 로딩이 잘 되고 있는것을 볼 수 있다.
로딩이 진행되는 정도는 log를 찍도록 설정해뒀다.
무거운 씬을 로딩할 땐 저것보다 느리게 로딩될 것이다.
이렇게 비동기로 씬을 호출하는 방법을 알아봤다.
다음엔 유니티의 비동기적 작업에 대해서 더 알아봐야겠다.
'Develop > Unity' 카테고리의 다른 글
[Unity] 유니티의 이벤트 - Action이벤트 (0) | 2024.10.24 |
---|---|
[Unity] 유니티에서 라디오버튼 구현하기 (Unity RadioButton) (0) | 2024.07.22 |
[Unity] 회원가입 시 주소 입력이 필요할때 (우편코드 및 도로명주소) - 행정안전부 도로명주소 api (0) | 2024.07.02 |
[Unity] C#에서 사용하는 get,set연산자 정리 (=>를 활용한 표현식) (0) | 2024.06.20 |
[Unity] 갑자기 스크립트 리로딩이 안될때 - 스크립트 수정 후 유니티에서 리로딩을 안할때 (0) | 2024.06.20 |