본문 바로가기
Utils

Unity, 플레이 모드가 아닌 상태에서 코루틴 사용하기

by Client. DJ 2022. 4. 6.
반응형

EditorCoroutine.cs

"Application.isPlaying == false"일 때, 코루틴을 사용하고 싶다면?

일반적이지 않은 상황에서 코루틴을 쓰고 싶은 경우 아래와 같이 해결할 수 있습니다.

  1. UnityEditor 네임스페이스를 이용하여 코루틴처럼 만들기
  2. 반복기(IEnumerator)의 특성을 이용하여 일반 함수처럼 돌려쓰기
  3. 유니티 지원 코루틴 패키지 설치하기

1. UnityEditor 네임스페이스를 이용하여 코루틴처럼 만들기

UnityEditor.EditorApplication.update 델리게이트를 통하여 프레임마다 함수를 호출하는 방법입니다.

아래의 코드를 작성합니다.

EditorCoroutine.cs

#if UNITY_EDITOR
    public class EditorCoroutine
    {
        public static EditorCoroutine StartCoroutine(IEnumerator _routine)
        {
            EditorCoroutine coroutine = new EditorCoroutine(_routine);
            coroutine.Start();
            return coroutine;
        }

        readonly IEnumerator routine;
        private EditorCoroutine(IEnumerator _routine) => routine = _routine;

        private void OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode mode)
        {
            if (mode == UnityEngine.SceneManagement.LoadSceneMode.Single)
                UnityEditor.EditorApplication.update -= Update;
        }

        private void Start()
        {
            UnityEditor.EditorApplication.update += Update;
            UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;
        }
        private void Stop()
        {
            UnityEditor.EditorApplication.update -= Update;
            UnityEngine.SceneManagement.SceneManager.sceneLoaded -= OnSceneLoaded;
        }

        private void Update()
        {
            if (!routine.MoveNext()) Stop();
        }
    }
#endif

사용 방법은 아래와 같습니다.

EditorCoroutine.StartCoroutine(코루틴함수());

평소와 같이, 코루틴을 사용하 듯 사용이 가능해집니다. (비플레이 모드 & 에디터 모드에서 한정)

 

+TIP) 플레이모드가 아닌 상태에서 코루틴으로 간단하게 웹 요청하기

public void WebRequest(string uri) => EditorCoroutine.StartCoroutine(Request(uri));

private IEnumerator Request(string uri)
{
    using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
    {
        yield return webRequest.SendWebRequest();
        string[] pages = uri.Split('/');
        int page = pages.Length - 1;

        if (webRequest.isNetworkError)
        {
            Debug.Log(pages[page] + ": Error: " + webRequest.error);
        }
        else
        {
            //Debug.Log(pages[page] + ":\nReceived: " + webRequest.downloadHandler.text);
            pages[page] = pages[page].Replace("?", "\n");
            pages[page] = pages[page].Replace("&", "\n");
            Debug.Log(pages[page]);
        }
    }
}

 

2. 반복기(IEnumerator)의 특성을 이용하여 일반 함수처럼 돌려쓰기

var enumerator = 코루틴함수();
while (enumerator.MoveNext()) { }

코루틴은 반복기의 형태로 사용되고 있으며, 매 반복 구간마다 yield return에 걸려있는 조건을 체크하면서 프레임마다 기다리는 방식입니다. 하지만 위와 같이 사용하면 조건을 무시한채 함수처리를 하여, 사실상 void 함수와 같은 형태로 작동됩니다. 이는 에디터모드가 아니어도 사용이 가능합니다.

 

3. 유니티 지원 패키지

유니티 측에서도 지원 중인 패키지로 에디터 코루틴을 지원하고 있습니다. "com.unity.editorcoroutines"로 방문하시면 패키치 설치 안내와 가이드를 볼 수 있습니다.

 

아래는 유니티 코루틴 API 가이드에서 제공하는 예제입니다.

using System.Collections;
using UnityEngine;
using Unity.EditorCoroutines.Editor;	// 패키지 설치 필요
using UnityEditor;

public class MyEditorWindow : EditorWindow
{
    IEnumerator PrintEachSecond()
    {
        var waitForOneSecond = new EditorWaitForSeconds(1.0f);	// 캐싱

        while (true)
        {
            yield return waitForOneSecond;
            Debug.Log("Printing each second");
        }
    }
}

위와 같이 패키지 설치 이후, "using Unity.EditorCoroutines.Editor;"  선언해주면 에디터 코루틴을 이용할 수 있습니다. 짧은 예문에도 캐싱을 찾아볼 수 있네요. 필요하다면 캐싱 클래스를 작성해도 좋을 것 같습니다.

코루틴 캐싱

예제 : 유니티, 코루틴 최적화(Coroutine Yield Instruction)

마무리

예전에 에디터 상태에서도 코루틴 처리가 필요한 작업이 있었습니다. 비 프로그래머 파트에게 유틸리티를 제공해주는 과정에서 작성을 했던 기억이 나네요. 누군가에게는 필요한 글이 되길바랍니다.😊

반응형

댓글