Unity

Unity MonoBehaviour, 코루틴 자주 쓰이는 기본 함수 문서 정리 1

뽀또치즈맛 2025. 4. 5. 20:08

 

항목 순서

  1. Invoke
  2. Coroutine
  3. StartCoroutine
  4. YieldInstruction
  5. WaitForSeconds
  6. WaitForEndOfFrame
  7. WaitForSecondsRealtime
  8. WaitUntil
  9. WaitWhile

 

Invoke

 

선언(Declaration)

 

public void Invoke (string methodName, float time);

 

정의(Description)

 

Invoke 메서드는 시간(초) 단위로 메서드를 호출한다.

만약 타임을 0으로 정하고, 첫 프레임 업데이트 이전에 

Invoke 함수를 호출하게 된다면,

해당 메서드는 다음 Update 사이클이 실행될 때

MonoBehaviour.Update가 호출되기 직전에 실행된다.

이런 경우라면 차라리 함수를 직접 호출하는 것이 더 좋다.

 

 

참고(Note)  : 시간을 음수 값으로 설정하는 것은 0으로 설정하는 것과 동일하다.

 

다른 경우에는, 메서드가 실행되는 순서는 Invoke가 호출된 시점에 따라 달라진다.

메서드에 매개변수를 전달해야 할 필요가 있다면,

Coroutine을 사용하는 것을 고려하는 편이 좋다.

코루틴은 또한 이 경우에 더 나은 성능을 제공한다.

 

 

사용 예시 코드

using UnityEngine;
using System.Collections.Generic;

public class ExampleScript : MonoBehaviour
{
    // Launches a projectile in 2 seconds

    Rigidbody projectile;

    void Start()
    {
        Invoke("LaunchProjectile", 2.0f);
    }

    void LaunchProjectile()
    {
        Rigidbody instance = Instantiate(projectile);
        instance.velocity = Random.insideUnitSphere * 5.0f;
    }
}

 

 

Coroutine

 

정의(Description)

 

MonoBefaviour.StartCouroutine은 Coroutine을 반환한다.

이 클래스의 인스턴스는 해당 코루틴을 참조하기 위한 용도로만 사용되며,

노출된 속성이나 함수는 가지고 있지 않다.

 

코루틴은 실행을 일시적으로 중단했다가 (yield)

주어진 YieldInstruction이 완료될 때까지 기다릴 수 있는 함수이다.

 

 

사용 예시 코드

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    IEnumerator WaitAndPrint()
    {
        // suspend execution for 5 seconds
        yield return new WaitForSeconds(5);
        print("WaitAndPrint " + Time.time);
    }

    IEnumerator Start()
    {
        print("Starting " + Time.time);

        // Start function WaitAndPrint as a coroutine
        yield return StartCoroutine("WaitAndPrint");
        print("Done " + Time.time);
    }
}

 

 

일반적인 Start 사용 예시 코드

 

using UnityEngine;
using System.Collections;

// In this example we show how to invoke a coroutine and execute
// the function in parallel.  Start does not need IEnumerator.

public class ExampleClass : MonoBehaviour
{
    private IEnumerator coroutine;

    void Start()
    {
        // - After 0 seconds, prints "Starting 0.0 seconds"
        // - After 0 seconds, prints "Coroutine started"
        // - After 2 seconds, prints "Coroutine ended: 2.0 seconds"
        print("Starting " + Time.time + " seconds");

        // Start function WaitAndPrint as a coroutine.

        coroutine = WaitAndPrint(2.0f);
        StartCoroutine(coroutine);

        print("Coroutine started");
    }

    private IEnumerator WaitAndPrint(float waitTime)
    {
        yield return new WaitForSeconds(waitTime);
        print("Coroutine ended: " + Time.time + " seconds");
    }
}

 

 

StartCoroutine

 

선언 (Declaration)

public Coroutine StartCoroutine(IEnumerator routine);

 

정의 (Description)

이 메서드는 코루틴을 시작한다.

 

코루틴의 실행은 yield 문을 상태를 사용하여 언제든 중단할 수 있다.

yield 문이 사용되면 코루틴은 실행을 일시 중단하고,

다음 프레임에 자동으로 다시 실행을 재개한다.

 

코루틴은 여러 프레임에 걸친 동작을 모델링할 때 매우 유용하다.

StartCoroutine 메서드는 첫 번째 yield return에서 반환되지만,

이 값을 yield 할 수도 있으며,

이 경우 해당 코루틴이 모두 끝날 때까지 기다린다.

코루틴은 실행 순서와 종료 순서가 반드시 같다고 보장되지 않으며,

같은 프레임 안에 종료되더라도 순서는 다를 수 있다.

 

(=> 사실 위 문단은 잘 이해가 가지 않는다.

아마 필자의 개인적인 견해로는
지금은 내부 구현이 어떻게 되어있을지 감이 잘 안와서

해당 내용이 잘 이해가 안된다고 생각한다.

 

따라서 이를 잘 이해하기 위해서는

필자의 개인적인 관점으로는

쓰레드나 os적인 관점에서도 꾸준히 지식을 축적해나가고,

엔진 밑단 구현 관련 코드에 자주 노출되가면서

엔진 위에서 코루틴을 적재적소에 사용하는 코드에도 자주 노출되어야

해당 기능에 대한 감이 올 것 같다.)

 

null을 포함한 어떤 타입이든 yield하게 되면,

그 코루틴의 실행은 나중 프레임에 다시 재개된다.

 

참고 (Note)

  • MonoBehaviour.StopCoroutine 또는 
    MonoBehaviour.StopAllCoroutines를 사용하여 코루틴을 중단할 수 있다.

  • MonoBehaviour가 파괴되거나
    그에 속한 GameObject가 비할성화되면 코루틴도 함께 중단된다.

  • 단, MonoBehaviour만 비활성화되었을 경우에는 코루틴은 중단되지 않는다.

 

이해 가능하도록 돕는 코드 1

using UnityEngine;
using System.Collections;


public class ExampleClass : MonoBehaviour
{
    // In this example we show how to invoke a coroutine and
    // continue executing the function in parallel.

    private IEnumerator coroutine;

    void Start()
    {
        // - After 0 seconds, prints "Starting 0.0"
        // - After 0 seconds, prints "Before WaitAndPrint Finishes 0.0"
        // - After 2 seconds, prints "WaitAndPrint 2.0"
        print("Starting " + Time.time);

        // Start function WaitAndPrint as a coroutine.

        coroutine = WaitAndPrint(2.0f);
        StartCoroutine(coroutine);

        print("Before WaitAndPrint Finishes " + Time.time);
    }

    // every 2 seconds perform the print()
    private IEnumerator WaitAndPrint(float waitTime)
    {
        while (true)
        {
            yield return new WaitForSeconds(waitTime);
            print("WaitAndPrint " + Time.time);
        }
    }
}

 

이해 가능하도록 돕는 코드2

using UnityEngine;
using System.Collections;


public class ExampleClass : MonoBehaviour
{
    // In this example we show how to invoke a coroutine and
    // continue executing the function in parallel.

    private IEnumerator coroutine;

    void Start()
    {
        // - After 0 seconds, prints "Starting 0.0"
        // - After 0 seconds, prints "Before WaitAndPrint Finishes 0.0"
        // - After 2 seconds, prints "WaitAndPrint 2.0"
        print("Starting " + Time.time);

        // Start function WaitAndPrint as a coroutine.

        coroutine = WaitAndPrint(2.0f);
        StartCoroutine(coroutine);

        print("Before WaitAndPrint Finishes " + Time.time);
    }

    // every 2 seconds perform the print()
    private IEnumerator WaitAndPrint(float waitTime)
    {
        while (true)
        {
            yield return new WaitForSeconds(waitTime);
            print("WaitAndPrint " + Time.time);
        }
    }
}

 

 

YieldInstruction

 

정의(Description)

모든 yield 명령의 기본 클래스가 다.

 

자세한 내용은

WaitForSeconds, WaitForFixedUpdate, Coroutine

그리고

MonoBehaviour.StartCorountine에 적혀있다.

 

 

WaitForSeconds

 

정의(Description)

 

주어진 시간(초) 동안 코루틴의 실행을 Time.timeScale을 기준으로 일시 중단한다.

실제로 중단되는 시간은

given time / Time.timeScale과 같다.

 

스케일이 적용되지 않은 실제 시간 기준으로 대기하고 싶다면

WaitForSecondRealtime을 사용하는 것이 좋다.

WaitForSeconds는 코루틴에서 yield 문과 함께 사용할 때만 동작한다.

 

다음과 같은 요인들 때문에 실제 대기 시간은 지정한 시간과 정확하게 일치하지 않을 수 있다.

 

  • "Start waiting at the end of the current frame"
    현재 프레임이 끝나는 시점에서 대기가 시작될 수 있다.
    이 말이 무슨 뜻이냐면
    예를 들어 t초 동안 대기하는 WaitForSeconds가 매우 긴 프레임
    (ex. 메인 스레드를 블로킹하는 synchronous loading(동기식 로딩) 중에
    호출되면, 코루틴은 호출 시점으로부터 t초 후가 아닌,
    해당 프레임이 끝난 시점으로부터 t초 후에 재개된다.
     
  • "Allow the coroutine to resume on the first frame after t seconds has passed,
    not exactly after 't' seconds has passed"
    정확히 t초 후가 아닌,
    t초가 지난 이후에 첫 프레임에서 코루틴이 재개된다.
    즉, 프레임 단위의 처리 특성상 약간의 오차가 발생할 수 있다.

 

생성자(Constructors)

Constructor Description
WaitForSeconds 스케일된 시간 기준으로 주어진 초만큼 코루틴 실행을 일시 중단한다.

 

 

WaitForEndOfFrame

 

정의 (Description)

WaitForEndOfFrame은 Unity가 모든 카메라와 GUI를 렌더링한 프레임의 끝까지 기다린다.

즉, 화면에 프레임이 실제로 표시되기 직전까지 대기한다.

 

이 기능은 화면에 렌더링된 내용을 텍스처로 읽어오거나,

이를 이미지 파일로 인코딩하여 저장할 때 유용하다.

(ex. Texture2D.ReadPixels, Texture2D.Texture2D 등을 사용할 수 있다.)

 

Game 뷰에서 Scene 뷰로 전환하면 WaitForEndOfFrame이 멈춘다.

이 코루틴은 Game뷰로 다시 전환될 때 다시 실행된다.

이러한 현상은 Unity 에디터 안에서 실행 중일 때만 발생한다.

 

Note :

이 코루틴은 Unity 에디터의 배치 모드(batch mode)에서 호출되지 않는다.

자세한 내용은 Command line arguments 를 알아보는 것이 좋다.

 

++

+ Command-line arguments

Unity 에디터와 독립 실행형 (Standalone) 플레이어 애플리케이션은

macOS의 터미널이나 Windows의 명령 프롬프트(Command Prompt)를 통해

커맨드 라인에서 실행할 수 있다.

 

이번 섹션에서는 커맨드 라인에서

Unity Editor나 Player를 실행할 때 동작을 변경할 수 있는

커맨드 라인 인자 (command-line arguments)를 설명한다.

  • Unity Editor command-line arguments
    Unity 에디터용 커맨드 라인 인자
    커맨드 라인에서 Unity 에디터를 실행할 때 사용할 수 있는 인자 목록이다.

  • Unity standalone Player command-line arguments:
    Unity 독립 실행형 플레이어용 커맨드 라인 인자
    빌드된 플레이어 애플리케이션을 커맨드 라인에서
    실행할 때 사용할 수 있는 인자 목록이다.

  • Android Player command-line arguments: 
    Android 플레이어를 실행할 때 커맨드 라인 인자를 전달하는 방법에 대한 설명이다.

  • CLIBatchmodeCoroutines: 
    Unity 에디터 또는 독립 실행형 플레이어를 
    배치 모드로 실행될 때 사용할 수 있는 Unity의 기능들에 대한 설명이다.

 

++

 

WaitForEndOfFrame 예시 코드

using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    // Take a shot immediately
    IEnumerator Start()
    {
        UploadPNG();
        yield return null;
    }

    IEnumerator UploadPNG()
    {
        // We should only read the screen buffer after rendering is complete
        yield return new WaitForEndOfFrame();

        // Create a texture the size of the screen, RGB24 format
        int width = Screen.width;
        int height = Screen.height;
        Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);

        // Read screen contents into the texture
        tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        tex.Apply();

        // Encode texture into PNG
        byte[] bytes = tex.EncodeToPNG();
        Destroy(tex);

        // For testing purposes, also write to a file in the project folder
        // File.WriteAllBytes(Application.dataPath + "/../SavedScreen.png", bytes);


        // Create a Web Form
        WWWForm form = new WWWForm();
        form.AddField("frameCount", Time.frameCount.ToString());
        form.AddBinaryData("fileUpload", bytes);

        // Upload to a cgi script
        var w = UnityWebRequest.Post("http://localhost/cgi-bin/env.cgi?post", form);
        yield return w.SendWebRequest();
        if (w.result != UnityWebRequest.Result.Success)
            print(w.error);
        else
            print("Finished Uploading Screenshot");
        yield return null;
    }
}

위 코드는

1. 게임 시작 시 자동 실행된다

2. 현재 화면을 캡처하고

3. PNG로 인코딩한 뒤

4. 웹 서버로 업로드하는 로직을 가진다.

 

 

WaitForEndOfFrame 예시 코드 2

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour
{
    // A script that shows destination alpha channel in the game view.

    Material mat;

    void CreateMaterial()
    {
        // Unity has a built-in shader that is useful for drawing
        // simple colored things. In this case, we just want to use
        // a blend mode that inverts destination colors.
        var shader = Shader.Find("Hidden/Internal-Colored");
        mat = new Material(shader);
        mat.hideFlags = HideFlags.HideAndDontSave;
        // Set blend mode to show destination alpha channel.
        mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstAlpha);
        mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
        // Turn off backface culling, depth writes, depth test.
        mat.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
        mat.SetInt("_ZWrite", 0);
        mat.SetInt("_ZTest", (int)UnityEngine.Rendering.CompareFunction.Always);
    }

    public IEnumerator Start()
    {
        CreateMaterial();
        while (true)
        {
            // Wait until all rendering + UI is done.
            yield return new WaitForEndOfFrame();
            // Draw a quad that shows alpha channel.
            GL.PushMatrix();
            GL.LoadOrtho();
            mat.SetPass(0);
            GL.Begin(GL.QUADS);
            GL.Vertex3(0, 0, 0);
            GL.Vertex3(1, 0, 0);
            GL.Vertex3(1, 1, 0);
            GL.Vertex3(0, 1, 0);
            GL.End();
            GL.PopMatrix();
        }
        yield return null;
    }
}

 

이 스크립트는 화면에 알파 채널을 시각화해서 표시하는 코드이다.

랜더링이 끝난 후 GL API를 사용해 알파 채널을 보여주는 사각형을 그린다.

 

위 코드를 기반으로
투명도 정보를 추출하거나 저장하는 방식의 코드를 구현할 수 있다.

 

위 코드를 요약하자면 다음과 같다.

 

기능 설명
Meterial 내부 컬러 셰이더로 알파 채널만 보이게 설정한다.
WaitForEndOfFrame 프레임 렌더링이 끝나고 나서 실행된다.
GL API 화면 전체에 알파 채널 정보를 덮어 그린다.
용도 디버깅 시 알파 채널 시각화 EX) UI 투명도 확인 등

 

 

 

WaitForSecondsRealtime

 

정의 (Description)

WaitForSecondsRealtime은 스케일이 적용되지 않은 시간 
즉, unscaled time 을 기준으로 주어진 초 동안 코루틴 실행을 일시 중단한다.

 

  • 이는 Time.timeScale의 영향을 받지 않으며,
    게임이 일시 정지 중이어도 계속 시간이 흐른다는 뜻이다.

  • Time.timeScale을 사용하는 대기를 원한다면 
    WaitForSeconds를 사용하는 것이 좋다.

  • WaitForSecondsRealtime은 코루틴에서
    yield문과 함께 사용할 때만 작동된다.

 

사용 예시 코드

using UnityEngine;
using System.Collections;

public class WaitForSecondsExample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Example());
    }

    IEnumerator Example()
    {
        print(Time.time);
        yield return new WaitForSecondsRealtime(5);
        print(Time.time);
    }
}

 

같이 보면 좋을 문서는

MonoBehaviour.StartCoroutine이 있다.

 

Properties

Properties(속성) 설명
waitTime yield 명령이 대기할 초 단위 시간을 나타낸다. (unscaled time 기준)

 

 

Constructors

Consturctors(생성자) 설명
WaitForSeconds
Realtime
스케일되지 않은 시간(unscaled time) 기준으로 주어진 초 동안 대기하는 yield 명령을 생성한다.

 

 

Inherited Members

Inherited Members
(상속된 멤버)
설명
keepWaiting 코루틴을 계속 일시 중단 상태로 유지하야 하는지를 나타낸다.

 

 

WaitUntil

 

정의 (Description)

WaitUntil은 전달된 델리게이트(조건 함수)가 true를 반환할 때까지

코루틴 실행을 일시 중단한다.

오직 코루틴 안에서 yield 문과 함께 사용할 수 있다.

 

전달된 조건 함수(delegate)는 매 프레임마다 실행되며,

MonoBehaviour.Update가 끝난 후 
MonoBehaviour.LateUpdate가 호출되기 전 사이에 평가된다.

조건이 true를 반환하면

코루틴의 실행이 그 지점에서 다시 시작된다.

 

관련된 기능들:
AsyncOperation,

WaitForEndOfFrame,

WaitForFixedUpdate,

WaitForSeconds,

WaitForSecondsRealtime,

WaitWhile

 

참고 예제 코드

using UnityEngine;
using System.Collections;

public class WaitUntilExample : MonoBehaviour
{
    public int frame;

    void Start()
    {
        StartCoroutine(Example());
    }

    IEnumerator Example()
    {
        Debug.Log("Waiting for princess to be rescued...");
        yield return new WaitUntil(() => frame >= 10);
        Debug.Log("Princess was rescued!");
    }

    void Update()
    {
        if (frame <= 10)
        {
            Debug.Log("Frame: " + frame);
            frame++;
        }
    }
}

 

참고 예제 코드 2

 

예시로는 다음과 같은 식으로 사용된다.

yield return new WaitUntil(() => Input.GetKeyDown(KeyCode.Space));

 

사용자가 스페이스바를 누를 때까지 코루틴이 멈춰 있다가,
누르면 다음 줄로 진행된다.

 

 

Constructors

onsturctors(생성자) 설명
WaitUntil 전달된 델리게이트를 평가하는 yield 명령을 초기화한다.
->  해당 함수가  true를 반환할 때까지 코루틴을 일시 중단한다.

 

 

Inherited Members 

Inherited Members
(상속된 멤버)
설명
keepWaiting 코루틴을 계속 일시 중단 상태로 유지할지 여부를 나타낸다
-> 조건 함수가 false일 경우 keepWaiting은 true이며,
-> 조건이 true가 되면 keepWaiting이 false가 되어
코루틴이 다시 실행된다.

 

 

 WaitWhile

 

정의(Description)

 

WaitWhile은 전달된 델리게이트가 false를 반환할 때까지 코루틴의 실행을 일시 중단한다.

이 기능은 코루틴 내에서 yield 문과 함께 사용해야 한다.

 

전달된 조건 함수는 매 프레임마다 평가되어,

MonoBehaviour.Update 이후,

MonoBehaviour.LateUpdate 이전에 실행된다.

 

이 함수가 false를 반환하는 순간,

코루틴의 실행이 다시 시작된다.

 

 

사용 예시 코드 1

using UnityEngine;
using System.Collections;

public class WaitWhileExample : MonoBehaviour
{
    public int frame;

    void Start()
    {
        StartCoroutine(Example());
    }

    IEnumerator Example()
    {
        Debug.Log("Waiting for prince/princess to rescue me...");
        yield return new WaitWhile(() => frame < 10);
        Debug.Log("Finally I have been rescued!");
    }

    void Update()
    {
        if (frame <= 10)
        {
            Debug.Log("Frame: " + frame);
            frame++;
        }
    }
}

 

 

사용 예시 코드 2

// 어떤 버튼이 눌려 있는 동안 기다림
yield return new WaitWhile(() => Input.GetMouseButton(0));

마우스 왼쪽 버튼을 누르고 있는 동안에는 코루틴이 멈추고,

버튼에서 손을 떼면 계속 실행된다.

 

WaitUntil과 반대로 동작하므로,

조건이 true일 때 멈추고 false일 때 통과하는 구조이다.

 

 

참고 자료:
AsyncOperation,

WaitForEndOfFrame,

WaitForFixedUpdate,

WaitForSeconds,

WaitForSecondsRealtime,

WaitUntil

 

Constructors

Constructor (생성자) 설명
WaitWhile 전달된 델리게이트(조건 함수)를 평가하는 yield 명령을 초기화한다.
조건 함수가 false를 반환할 때까지 코루틴 실행이 일시 중단된다.

 

 

Inherited Members

Inherited Members
(상속된 멤버)
설명
keepWaiting 코루틴을 계속 일시 중단할지 여부를 타나낸다.
조건 함수가 true일 때는 keepWaiting == true로 유지되고,
조건 함수가 false가 되면 keepWaiting == false로 바뀌며 코루틴이 다시 실행된다.

 

 

WaitWhile은 WaitUntil과 정 반대 조건을 기다리는 코루틴 제어 도구이다.

 

 

출저

https://docs.unity3d.com/6000.0/Documentation/ScriptReference/

 

'Unity' 카테고리의 다른 글

Unity - BroadCasting, SendMessage, BroadcastMessage  (0) 2025.03.16
유니티 적군 상태 변환  (0) 2024.08.09
코루틴  (0) 2024.02.26
Instantitate()와 Destroy()함수  (0) 2024.02.15
트리거 콜라이더  (1) 2024.02.11