개발/Unity

유니티 - yield return null vs WaitForEndOfFrame 비교하기

피로물든딸기 2022. 10. 3. 10:08
반응형

Unity 전체 링크

 

코루틴에서 yield return에는 여러 종류가 있다.

 

주로 사용하는 yield return null, WaitForEndOfFrame, WaitForFixedUpdate 등이 있는데

실제로 큰 차이는 없어 보이지만, 미세하게 타이밍을 알아야할 때는 구분해서 사용해야 한다.

 

유니티 라이프 사이클을 보면 언제 yield가 리턴되는지 알 수 있다.

 

LifeCycleYieldReturn1.cs를 아무 오브젝트에 추가한 후 게임을 실행시키고, 오브젝트를 제거해보자. (OnDestroy)

로그를 텍스트로 저장하기 위해 StreamWriter를 사용하였다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;

public class LifeCycleYieldReturn1 : MonoBehaviour
{
    StreamWriter writer;
    void saveLog(string logString, string stackTrace, LogType type)
    {
        string currentTime = DateTime.Now.ToString(("HH:mm:ss"));
        writer.WriteLine($"[{currentTime}] {logString}");
    }

    void Awake()
    {
        writer = new StreamWriter("Assets/Log/mylog.txt");
        Application.logMessageReceived += saveLog;

        Debug.Log("Test 1 Awake");
    }

    void OnEnable()
    {
        Debug.Log("Test 1 OnEnable");
    }

    void Start()
    {
        Debug.Log("Test 1 Start");

        StartCoroutine(yieldReturnWaitForFixedUpdate());
        StartCoroutine(yieldReturnNull());
        StartCoroutine(yeildReturnWaitForEndOfFrame());
    }

    IEnumerator yieldReturnWaitForFixedUpdate()
    {
        while (true)
        {
            Debug.Log("Test 1 yieldReturnWaitForFixedUpdate");
            yield return new WaitForFixedUpdate();
        }
    }

    void FixedUpdate()
    {
        Debug.Log("Test 1 FixedUpdate");
    }

    void Update()
    {
        Debug.Log("Test 1 Update");
    }
    void LateUpdate()
    {
        Debug.Log("Test 1 LateUpdate");
    }

    IEnumerator yieldReturnNull()
    {
        while (true)
        {
            Debug.Log("Test 1 yieldReturnNull");
            yield return null;
        }
    }

    void OnDrawGizmos()
    {
        Debug.Log("Test 1 OnDrawGizmos");
    }

    void OnGUI()
    {
        Debug.Log("Test 1 OnGUI");
    }

    IEnumerator yeildReturnWaitForEndOfFrame()
    {
        while (true)
        {
            Debug.Log("Test 1 yeildReturnWaitForEndOfFrame");
            yield return new WaitForEndOfFrame();
        }
    }

    void OnDisable()
    {
        Debug.Log("Test 1 OnDisable");
    }

    void OnDestroy()
    {
        Debug.Log("Test 1 OnDestroy");

        Application.logMessageReceived -= saveLog;

        writer.Flush();
        writer.Close();
    }
}

 

로그 출력 결과는 다음과 같다.

[18:03:14] Test 1 Awake
[18:03:14] Test 1 OnEnable
[18:03:14] Test 1 Start

[18:03:14] Test 1 yieldReturnWaitForFixedUpdate
[18:03:14] Test 1 yieldReturnNull
[18:03:14] Test 1 yeildReturnWaitForEndOfFrame

[18:03:14] Test 1 FixedUpdate
[18:03:14] Test 1 yieldReturnWaitForFixedUpdate

[18:03:16] Test 1 Update
[18:03:16] Test 1 yieldReturnNull
[18:03:16] Test 1 LateUpdate
[18:03:16] Test 1 OnDrawGizmos
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 yeildReturnWaitForEndOfFrame

[18:03:16] Test 1 Update
[18:03:16] Test 1 yieldReturnNull
[18:03:16] Test 1 LateUpdate
[18:03:16] Test 1 OnDrawGizmos
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 yeildReturnWaitForEndOfFrame

[18:03:16] Test 1 Update
[18:03:16] Test 1 yieldReturnNull
[18:03:16] Test 1 LateUpdate
[18:03:16] Test 1 OnDrawGizmos
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 yeildReturnWaitForEndOfFrame


[18:03:16] Test 1 FixedUpdate
[18:03:16] Test 1 yieldReturnWaitForFixedUpdate

[18:03:16] Test 1 Update
[18:03:16] Test 1 yieldReturnNull
[18:03:16] Test 1 LateUpdate
[18:03:16] Test 1 OnDrawGizmos
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 yeildReturnWaitForEndOfFrame

[18:03:16] Test 1 Update
[18:03:16] Test 1 yieldReturnNull
[18:03:16] Test 1 LateUpdate
[18:03:16] Test 1 OnDrawGizmos
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 OnGUI
[18:03:16] Test 1 yeildReturnWaitForEndOfFrame

...

[18:03:16] Test 1 OnDisable
[18:03:16] Test 1 OnDestroy

 

Update는 매 프레임마다 호출되고, LateUpdate는 모든 Update가 호출된 후 마지막으로 실행되는 함수다.

FixedUpdate는 Fixed TimeStep에 설정된 값에 따라 일정시간마다 호출된다.

위의 경우는 FixedUpdate 한 번 Update가 두 번 호출되고 있다.

 

WaitForFixedUpdateFixedUpdate가 종료된 후 호출되고, 

yield return nullUpdate 후, WaitForEndOfFrame은 프레임이 종료된 후(OnGUI 다음)에 호출되었다.

 

즉, 코루틴이더라도 유니티 LifeCycle에 따라 호출되는 위치가 다르므로, 

정확한 타이밍에 호출해야 불필요한 버그를 줄일 수 있다.

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형