본문 바로가기
개발/Unity

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

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

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

반응형

댓글