Unity 강의 정리 5-8장: C# 프로그래밍 [중급] (1/2) : 코루틴🎮

나무에물주기·2023년 9월 6일
1

Unity

목록 보기
17/21
post-thumbnail

인프런에 있는 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리하는 글입니다!

유니티에서 코루틴(Coroutine) 이해하기 🌟


1. Fade in, Fade out 효과 만들기 🎨

초기 구현: For문 활용

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Fade : MonoBehaviour
{
    public Image fadeImage;

    void Start()
    {
        FadeIn();
    }

    void FadeIn()
    {
        Color startColor = fadeImage.color;

        for(int i = 0; i < 100; i++)
        {
            startColor.a = startColor.a - 0.01f;
            fadeImage.color = startColor;
        }
    }
}
  • public Image fadeImage: Unity의 UI Image 컴포넌트를 참조한다.
  • FadeIn(): Fade in 효과를 구현한 메서드이다.
  • for(int i = 0; i < 100; i++): 0.01씩 알파 값을 줄여 페이드 인 효과를 구현한다.

이러한 방식은 간단하게 구현할 수 있으나, 프레임에 따라서 속도가 달라질 수 있다는 단점이 있다.

개선된 구현: 코루틴 활용

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Fade : MonoBehaviour
{
    public Image fadeImage;

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

    IEnumerator FadeIn()
    {
        Color startColor = fadeImage.color;

        for(int i = 0; i < 100; i++)
        {
            startColor.a = startColor.a - 0.01f;
            fadeImage.color = startColor;

            yield return new WaitForSeconds(0.01f);
        }
    }
}
  • StartCoroutine(FadeIn()): FadeIn 코루틴을 시작한다.
  • IEnumerator FadeIn(): 코루틴으로 구현한 Fade in 메서드이다.
  • yield return new WaitForSeconds(0.01f): 0.01초마다 알파 값을 줄여 페이드 인 효과를 구현한다.

코루틴을 활용하면 프레임에 영향을 받지 않는 일정한 속도로 페이드 인 효과를 구현할 수 있다.

메서드 호출: StartCoroutine()

StartCoroutine() 메서드는 Unity에서 코루틴을 시작하는 기본적인 방법이다. 이 메서드를 통해 지정된 코루틴이 실행되며, yield 키워드를 만나면 일시적으로 실행을 중단하고 대기한다. 이후 지정된 시간이나 조건을 만족하면 다시 실행을 재개한다.


2. 코루틴의 사용 문법 형식 📜

코루틴은 Unity에서 제공하는 특별한 메서드 형식이다. 일반 메서드와 다르게 IEnumerator를 반환형으로 가지며, yield 키워드를 사용하여 메서드의 실행을 일시 중단하고 재개할 수 있다.

기본 문법

IEnumerator CoroutineName()
{
	....
    yield return new WaitForSeconds(time);  // Wait for a certain time
}

코루틴 실행

코루틴은 StartCoroutine() 메서드를 사용하여 실행한다.

StartCoroutine("CoroutineName");

또는

StartCoroutine(CoroutineName());

코루틴 중단

StopCoroutine() 메서드를 사용하여 실행 중인 코루틴을 중단할 수 있다.

StopCoroutine("CoroutineName");

또는

StopCoroutine(CoroutineName());

3. 코루틴의 비동기 처리 🔄

스레딩과 코루틴의 차이점

스레딩과 코루틴은 모두 비동기 처리에 사용되지만, 몇 가지 중요한 차이점이 있다.

  1. 멀티스레딩: 멀티스레딩은 운영체제의 스케쥴러에 의해 여러 스레드가 관리된다. 이로 인해 스레드 사이에 경쟁 상태(race condition)나 데드락(deadlock) 등의 복잡한 문제가 발생할 수 있다.

  2. 싱글스레딩과 코루틴: Unity의 메인 루프는 싱글 스레드에서 실행된다. 코루틴은 이 싱글 스레드 내에서 '가상'의 병렬 처리를 가능하게 한다. 즉, 코루틴은 실제로는 병렬 처리가 아니며, 작업을 나눠서 수행하는 것에 가깝다.

비동기 vs 동기

  1. 동기 처리: 함수나 작업의 실행이 완료될 때까지 다음 작업이 대기하는 방식이다. 이로 인해 UI가 멈추거나 응답이 없을 수 있다.

  2. 비동기 처리 (멀티스레딩): 병렬로 여러 작업을 수행하므로, 하나의 작업이 완료되기를 기다리지 않고 다음 작업을 진행한다.

  3. 비동기 처리 (코루틴): 코루틴은 비동기처럼 보이지만, 실제로는 메인 스레드에서 일정 시간 동안 작업을 중단('yield')하고 다시 시작('resume')하여, 여러 작업을 수행할 수 있는 것처럼 보이게 한다.

코루틴의 비동기 처리의 장점

  • 게임 퍼포먼스 유지: 복잡한 로직이나 시간이 걸리는 작업을 비동기로 처리하여 게임의 퍼포먼스를 유지할 수 있다.

  • 코드 가독성 향상: 비동기 로직을 간결하게 표현하여 코드의 가독성을 향상시킬 수 있다.

  • 유연한 이벤트 처리: 다양한 이벤트를 쉽게 관리하고 실행 순서를 제어할 수 있다.

  • 스레딩의 복잡성 회피: 경쟁 상태나 데드락과 같은 멀티스레딩의 복잡한 문제를 피할 수 있다.

기본적인 비동기 처리 예시

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

public class HelloCoroutine : MonoBehaviour
{
    void Start()
    {
        StartCoroutine("HelloUnity");
    }

    IEnumerator HelloUnity()
    {
        Debug.Log("Hello");

        yield return new WaitForSeconds(3f); 

        Debug.Log("Unity");
    }
}
  • IEnumerator HelloUnity(): 코루틴 함수를 정의한다.
  • yield return new WaitForSeconds(3f): 3초 동안 작업을 일시 중단한다.
  • Debug.Log("Unity"): 3초 후에 "Unity" 문자열을 출력한다.

이러한 기본적인 구조를 통해, "Hello"와 "Unity" 사이에 3초의 딜레이를 생성할 수 있다.

복수의 코루틴 동시 실행

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

public class HelloCoroutine : MonoBehaviour
{
    void Start()
    {
        StartCoroutine("HelloUnity");
        StartCoroutine("HiCSharp");
        Debug.Log("End");
    }

    IEnumerator HelloUnity()
    {
        Debug.Log("Hello");

        yield return new WaitForSeconds(3f); 

        Debug.Log("Unity");
    }

    IEnumerator HiCSharp()
    {
        Debug.Log("Hi");

        yield return new WaitForSeconds(5f); 

        Debug.Log("CSharp");
    }
}
  • StartCoroutine("HelloUnity")StartCoroutine("HiCSharp"): 두 개의 다른 코루틴을 동시에 실행한다.
  • Debug.Log("End"): 이 코드는 코루틴이 완료되기를 기다리지 않고 바로 실행된다.

코루틴의 비동기 처리의 장점

  • 게임 퍼포먼스 유지: 복잡한 로직이나 시간이 걸리는 작업을 비동기로 처리하여 게임의 퍼포먼스를 유지할 수 있다.
  • 코드 가독성 향상: 비동기 로직을 간결하게 표현하여 코드의 가독성을 향상시킬 수 있다.
  • 유연한 이벤트 처리: 다양한 이벤트를 쉽게 관리하고 실행 순서를 제어할 수 있다.

4. yield 문법에 대해서 📘

yield의 기본 개념

yield 키워드는 C#에서 반복자(iterator)나 코루틴을 구현할 때 사용되는 키워드이다. Unity에서는 주로 코루틴을 구현할 때 사용된다. yield return 문을 만나면, 현재 코루틴의 실행을 일시적으로 중지하고 메인 스레드의 제어권을 Unity 엔진에 다시 넘긴다. 그리고 지정된 조건이 충족되면 코루틴의 실행을 다시 재개한다.

다양한 yield 유형

  1. yield return null;: 다음 프레임까지 코루틴의 실행을 중지한다.

  2. yield return new WaitForSeconds(seconds);: 지정된 시간(초) 동안 코루틴의 실행을 중지한다.

  3. yield return StartCoroutine("AnotherCoroutine");: 다른 코루틴이 완료될 때까지 현재 코루틴의 실행을 중지한다.

  4. yield return new WaitUntil(() => condition);: 지정된 조건이 true가 될 때까지 코루틴의 실행을 중지한다.

  5. yield return new WaitWhile(() => condition);: 지정된 조건이 false가 될 때까지 코루틴의 실행을 중지한다.

yield의 사용 사례

  1. 로딩 화면: 게임 리소스를 로딩하는 동안 사용자에게 로딩 화면을 보여주고 싶을 때, yield를 사용하여 로딩 작업을 비동기로 수행할 수 있다.
  2. 애니메이션: 캐릭터의 움직임이나 특정 이벤트를 시간에 따라 제어하려면 yield를 사용하여 간단하게 구현할 수 있다.
  3. 게임 로직: 특정 조건이 충족되면 게임 로직을 실행하려면, yield return new WaitUntil(() => condition);과 같이 사용할 수 있다.

yield의 제약 사항

  • yieldIEnumerator 리턴 타입을 가진 메서드 내에서만 사용 가능하다.

  • yieldtry-catch 블록 내에서는 사용할 수 없다. 하지만 try-finally 블록 내에서는 사용 가능하다.


정리 📝

  1. Fade in, Fade out 효과 만들기: 코루틴을 활용하여 게임에서 자주 보이는 페이드 인, 페이드 아웃 효과를 구현할 수 있다. 이를 위해 IEnumerator를 반환하는 메서드와 yield 문법을 사용한다.

  2. 코루틴의 비동기 처리: 코루틴은 Unity의 비동기 작업을 처리하기 위한 강력한 도구이다. 싱글 스레드 환경에서도 마치 멀티 스레드처럼 작동하여, 메인 스레드의 작업을 방해하지 않고 별도의 작업을 수행할 수 있다.

  3. yield 문법: yield는 코루틴의 실행을 일시적으로 중지하고, 특정 조건이 충족될 때까지 기다린 후 다시 실행을 재개하는 데 사용된다.

profile
개인 공부를 정리함니다

0개의 댓글