06
14

AsyncOperation이란?

비동기 작업을 나타내는 Unity의 타입

코루틴을 사용하여 비동기 작업을 조작할 때 주로 활용된다.
비동기 작업이 완료될 때까지 대기하거나 작업의 진행 상태를 업데이트할 수 있다.

사용 이유

Unity에서는 보통 작업이 순차적으로 실행되며, 한 작업이 끝나야 다음 작업이 실행된다.
이것을 동기적 작업이라고 한다.
예를 들어, 씬을 로드할 때나 에셋을 로드할 때는 로딩 작업이 완료될 때까지 대기하며,
그 후에 다음 작업을 수행한다.
하지만 Unity에서는 비동기 작업을 수행할 수 있는 기능들도 제공한다.
예를 들어, 비동기 씬 로딩을 위한 AsyncOperation을 사용하거나,
비동기적으로 에셋을 로드하는 함수를 호출할 수도 있다.
비동기 작업을 사용하면 여러 작업이 동시에 처리되며, 게임이 더 원활하게 실행될 수 있다.

활용되는 곳

주로 씬 로딩, 에셋 번들 로딩, 비동기적인 파일 로딩 등과 같은 비동기 작업을 처리하는 데 사용된다.

속성 설명

1. AsyncOperation 객체는 비동기 작업의 진행 상태와 결과에 대한 정보를 제공

2. AsyncOperation.isDone은 작업이 완료되었는지 여부를 나타내는 bool 값

3. AsyncOperation.progress는 작업의 진행 상태를 나타내는 0.0부터 1.0 사이의 값을 가진다.
   일반적으로 로딩 작업의 진행 상태를 표시하는 데 사용된다.

4. AsyncOperation.allowSceneActivation은 씬의 활성화 여부를 제어하는 속성이다. 일반적으로 씬이 완전히 로드된 후에 활성화되도록 설정한다.

예제 코드
- 비동기 씬 로딩

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    public void LoadSceneAsync(string sceneName)
    {
        StartCoroutine(LoadSceneAsyncCoroutine(sceneName));
    }

    private IEnumerator LoadSceneAsyncCoroutine(string sceneName)
    {
        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
        asyncLoad.allowSceneActivation = false;

        while (!asyncLoad.isDone)
        {
            // 로딩 진행 상태 업데이트
            float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
            Debug.Log("로딩 진행 상태: " + (progress * 100) + "%");

            if (asyncLoad.progress >= 0.9f)
            {
                // 로딩이 거의 완료되면 씬 활성화
                asyncLoad.allowSceneActivation = true;
            }

            yield return null;
        }
    }
}

예제 코드
- 비동기 에셋 번들 로딩

using UnityEngine;

public class AssetBundleLoader : MonoBehaviour
{
    public string assetBundleURL;

    private IEnumerator Start()
    {
        // 에셋 번들 비동기적으로 로드
        var request = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundleURL);
        yield return request.SendWebRequest();

        // 에셋 번들 가져오기
        AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(request);

        // 에셋 번들에서 원하는 에셋 로드
        GameObject prefab = assetBundle.LoadAsset<GameObject>("PrefabName");

        // 원하는 작업 수행
        Instantiate(prefab);

        // 에셋 번들 해제
        assetBundle.Unload(false);
    }
}
이 예제에서는 AsyncOperation이 직접 사용되지 않았지만,
대신 IEnumerator와 yield return을 사용하여 비동기적으로 AssetBundle을 로드하고 처리하는 방식을 구현했다.

IEnumerator은 Coroutine을 정의하기 위해 사용되며,
yield return 문은 Coroutine의 실행을 일시 중단하고, 다음 프레임이나 조건이 충족될 때까지 기다리는 역할을 한다.

이 예제에서 Start() 메서드는 Coroutine으로 정의되어 있으며,
yield return 문을 사용하여 AssetBundle을 비동기적으로 로드하고 처리한다.

UnityWebRequestAssetBundle.GetAssetBundle() 메서드는
UnityWebRequest를 사용하여 AssetBundle을 비동기적으로 요청하고,
yield return request.SendWebRequest()를 통해 요청이 완료될 때까지 기다린다.

그런 다음 DownloadHandlerAssetBundle.GetContent()를 사용하여 요청한 AssetBundle을 가져온다.
AssetBundle에서 원하는 에셋을 로드한 후 필요한 작업을 수행하고,
마지막으로 assetBundle.Unload(false)를 호출하여 AssetBundle을 해제한다.
COMMENT