코루틴이란?
코루틴은 IEnumerator를 반환하는 함수로, 비동기적으로 작업을 처리하거나 지연된 작업을 수행할 수 있습니다. yield를 사용하여 특정 시간 동안 대기하거나, 여러 프레임에 걸쳐 작업을 나누어 처리할 수 있습니다. 이는 게임에서 타이밍 제어나 비동기적 로딩, 애니메이션 제어 등 다양한 용도로 사용됩니다.
기본 사용법
코루틴은 다음과 같이 정의하고 호출할 수 있습니다:
using System.Collections;
using UnityEngine;
public class Greeting : MonoBehaviour
{
void Start()
{
StartCoroutine(GreetEverySecond());
}
IEnumerator GreetEverySecond()
{
while (true)
{
Debug.Log("Hello, World!");
yield return new WaitForSeconds(1f); // 1초마다 "Hello, World!" 출력
}
}
}
주요 yield 반환 타입
- WaitForSeconds: 지정한 시간 동안 대기
- WaitForFixedUpdate: 다음 FixedUpdate 호출 전까지 대기
- WaitForEndOfFrame: 현재 프레임이 끝날 때까지 대기
- CustomYieldInstruction: 사용자 정의 조건을 만족할 때까지 대기
고급 응용 사례
1. 비동기 로딩 및 프로그래스 바
게임 내에서 리소스(예: 씬, 텍스처 등)를 비동기적으로 로드하고, 로딩 상태를 사용자에게 표시할 수 있습니다.
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class AsyncLoader : MonoBehaviour
{
public Slider progressBar;
void Start()
{
StartCoroutine(LoadSceneAsync("GameScene"));
}
IEnumerator LoadSceneAsync(string sceneName)
{
AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName);
while (!asyncOperation.isDone)
{
progressBar.value = Mathf.Clamp01(asyncOperation.progress / 0.9f);
yield return null; // 프레임 단위로 진행 상태 확인
}
}
}
2. 애니메이션 및 타이밍 조절
특정 애니메이션 상태를 대기하거나 시간 기반의 애니메이션을 구현할 수 있습니다.
using System.Collections;
using UnityEngine;
public class AnimationController : MonoBehaviour
{
public Animator animator;
void Start()
{
StartCoroutine(PlayAnimationWithDelay("Jump", 2f));
}
IEnumerator PlayAnimationWithDelay(string animationName, float delay)
{
yield return new WaitForSeconds(delay); // 2초 대기
animator.Play(animationName);
}
}
3. 게임 이벤트 관리
게임 내에서 특정 조건이 충족될 때까지 대기하거나, 이벤트를 순차적으로 처리할 수 있습니다.
using System.Collections;
using UnityEngine;
public class EventManager : MonoBehaviour
{
public GameObject objectToActivate;
void Start()
{
StartCoroutine(HandleGameEvents());
}
IEnumerator HandleGameEvents()
{
yield return new WaitForSeconds(5f); // 5초 후 오브젝트 활성화
objectToActivate.SetActive(true);
yield return new WaitForSeconds(10f); // 10초 후 비활성화
objectToActivate.SetActive(false);
}
}
4. NPC 행동 패턴
코루틴을 사용하여 NPC의 행동을 순차적으로 처리하고, 시간 기반의 상태 전환을 구현할 수 있습니다.
using System.Collections;
using UnityEngine;
public class NPCBehavior : MonoBehaviour
{
public Transform[] waypoints;
private int currentWaypoint = 0;
void Start()
{
StartCoroutine(Patrol());
}
IEnumerator Patrol()
{
while (true)
{
Transform target = waypoints[currentWaypoint];
while (Vector3.Distance(transform.position, target.position) > 0.1f)
{
transform.position = Vector3.MoveTowards(transform.position, target.position, Time.deltaTime * 2f);
yield return null; // 매 프레임마다 NPC를 이동
}
currentWaypoint = (currentWaypoint + 1) % waypoints.Length;
yield return new WaitForSeconds(2f); // 2초 대기 후 다음 웨이포인트로 이동
}
}
}
코루틴 최적화 방법
코루틴을 효과적으로 사용하려면 다음과 같은 최적화 방법을 고려해야 합니다:
1. 불필요한 코루틴 최소화
코루틴이 너무 많으면 성능에 영향을 미칠 수 있습니다. 필요하지 않은 코루틴은 제거하고, 하나의 코루틴으로 여러 작업을 처리하도록 최적화합니다.
// 불필요한 코루틴 예시
IEnumerator Process1() { /* 작업 */ yield return null; }
IEnumerator Process2() { /* 작업 */ yield return null; }
// 최적화된 예시
IEnumerator ProcessAll()
{
yield return StartCoroutine(Process1());
yield return StartCoroutine(Process2());
}
2. 코루틴 종료 조건 명확히 설정
코루틴이 불필요하게 계속 실행되지 않도록 종료 조건을 명확히 설정합니다. yield break를 사용하여 코루틴을 명확하게 종료할 수 있습니다.
IEnumerator ExampleCoroutine()
{
while (true)
{
// 조건에 따라 종료
if (SomeCondition())
{
yield break;
}
yield return null;
}
}
3. WaitForSeconds 대신 WaitForSecondsRealtime 사용
게임이 일시 정지 상태일 때도 시간을 정확히 측정하고자 한다면 WaitForSecondsRealtime을 사용합니다.
// 일반적인 WaitForSeconds
yield return new WaitForSeconds(1f);
// 게임이 일시 정지 상태에서도 시간 측정 가능
yield return new WaitForSecondsRealtime(1f);
4. 매 프레임 호출되는 작업 최적화
매 프레임 호출되는 코루틴의 경우, 가능한 경우 yield return null 대신 yield return new WaitForSeconds를 사용하여 프레임 속도에 영향을 주지 않도록 합니다.
IEnumerator UpdatePerFrame()
{
while (true)
{
// 매 프레임 작업
yield return null;
}
}
5. 사용자 정의 YieldInstruction 활용
복잡한 조건이 필요할 경우, 사용자 정의 YieldInstruction을 만들어서 지연을 보다 세밀하게 제어할 수 있습니다.
public class CustomYieldInstruction : YieldInstruction
{
public override bool keepWaiting
{
get
{
// 사용자 정의 조건
return false;
}
}
}
// 사용 예시
IEnumerator UseCustomYield()
{
yield return new CustomYieldInstruction();
}
6. 미리 선언한 WaitForSeconds 객체 사용
private WaitForSeconds wait = new WaitForSeconds(2f);
// 반복적으로 사용
yield return wait;
결론
코루틴은 Unity에서 비동기 작업과 타이밍 제어를 유연하게 처리할 수 있는 방법입니다. 기본적인 사용법뿐만 아니라, 다양한 응용 사례와 최적화 방법을 이해하고 적용함으로써 게임의 성능을 효율적으로 관리할 수 있습니다.
'Unity > 정보' 카테고리의 다른 글
[Unity] 프리팹(Prefab) 기초 (0) | 2024.09.16 |
---|---|
[Unity] GPU Instancing (0) | 2024.09.13 |
[Unity] 휴머노이드 애니메이션을 활용한 상체와 하체의 방향 조정 방법 (0) | 2024.09.04 |
[Unity] AR 튜토리얼 (0) | 2024.08.17 |
[Unity] URP 데칼 프로젝터(Decal projector) 사용하기 (0) | 2024.07.09 |