Unity Background Process

FGPRJS·2022년 4월 22일
0

유니티는 싱글스레드 기반 작업을 수행한다.

하지만 코루틴을 통하여 백그라운드 작업을 수행할 수는 있다.

(C#의 Job System을 사용하면 Unity에서도 멀티스레드를 사용할 수 있다는 문서가 남아있으므로 추후 참고할 것)

코루틴

Unity에서 제공하는 코루틴 정보

It’s best to use coroutines if you need to deal with long asynchronous operations, such as waiting for HTTP transfers, asset loads, or file I/O to complete.

무언가를 로딩하거나 신호를 기다리는 백그라운드 작업의 용도와 비슷한 용도를 가졌다.

코루틴 예제

다음 링크에서 LoadSceneAsync함수와 코루틴을 어떻게 사용하는지 확인해보자.

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

public class Example : MonoBehaviour
{
    void Update()
    {
        // Press the space key to start coroutine
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Use a coroutine to load the Scene in the background
            StartCoroutine(LoadYourAsyncScene());
        }
    }

    IEnumerator LoadYourAsyncScene()
    {
        // The Application loads the Scene in the background as the current Scene runs.
        // This is particularly good for creating loading screens.
        // You could also load the Scene by using sceneBuildIndex. In this case Scene2 has
        // a sceneBuildIndex of 1 as shown in Build Settings.

        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("Scene2");

        // Wait until the asynchronous scene fully loads
        while (!asyncLoad.isDone)
        {
            yield return null;
        }
    }
}

상기 함수는 Scene을 Async하게 로딩하는 것을 목표로 한다.
LoadSceneAsync 함수에서 제공하는 Operation(진행도 및 완료 여부를 리턴한다.)을 while 루프로 체크하며 Done이 되지 않으면 계속 yield return으로 null을 리턴한다.

코루틴이 될 함수는 IEnumerator(열거형)를 리턴하는 함수여야 한다.

IEnumerator (열거형)

IEnumerator(열거형) 공식 문서

열거형 인터페이스는 제네릭이 아닌 모든 열거자의 기본 인터페이스입니다.

쉽게 이해하려면, 특정 Class가 foreach문을 사용하려면 IEnumerator를 인터페이스로 구현해야만 한다는 것으로 생각하면 된다.
관련 문서

using System;
using System.Collections;
namespace ConsoleEnum
{
    public class cars : IEnumerator,IEnumerable
    {
       private car[] carlist;
       int position = -1;
       //Create internal array in constructor.
       public cars()
       {
           carlist= new car[6]
           {
               new car("Ford",1992),
               new car("Fiat",1988),
               new car("Buick",1932),
               new car("Ford",1932),
               new car("Dodge",1999),
               new car("Honda",1977)
           };
       }
       //IEnumerator and IEnumerable require these methods.
       public IEnumerator GetEnumerator()
       {
           return (IEnumerator)this;
       }
       //IEnumerator
       public bool MoveNext()
       {
           position++;
           return (position < carlist.Length);
       }
       //IEnumerable
       public void Reset()
       {
           position = -1;
       }
       //IEnumerable
       public object Current
       {
           get { return carlist[position];}
       }
    }
  }

Yield

yield 공식 문서
yield 를 이해하기 위한 사이트

yield는 IEnumerator한 클래스에서 사용된다.

  • yield return
    • 컬렉션 데이터를 하나 리턴한다.
  • yield break
    • 더 이상 컬렉션 데이터에서 루프를 돌지 않는다.

C#에서 호출자가 yield를 가진 Iteration 메서드를 호출하면 다음과 같은 방식으로 실행된다.
즉, 호출자(A)가 IEnumerable을 리턴하는 메서드(B)를 호출하면, yield return문에서 하나의 값을 리턴하고, 해당 메서드(B)의 위치를 기억해 둔다.
호출자(A)가 다시 루프를 돌아 다음 값을 메서드(B)에 요청하면, 메서드의 기억된 위치 다음 문장부터 실행하여 다음 yield 문을 만나 값을 리턴한다.

profile
FGPRJS

0개의 댓글