본문 바로가기

유니티와 놀기

코루틴 뒤에 코루틴을 실행시키기

 만약 어떤 오브젝트가 시간에 따라 사라지거나 움직이는 기능을 만들고 싶다면 Update함수와 Time.deltaTime을 활용해 만들 수 있다. 하지만 이 방법은 하나뿐인 Update함수를 복잡하게 만든다. 이때 코루틴은 유니티에서 Update외 다른 루틴을 만들 수 있게 해준다.

 

public class MoveForSeconds : MonoBehaviour
{
    public int time;
    private Vector3 start;

    void Start()
    {
        start = transform.position;
    }

    public IEnumerator CoMoveForSeconds()
    {
        float timer = 0.0f;
        while (timer < time)
        {
            timer += Time.deltaTime;
            transform.position = start + Vector3.right * 10 * (timer / time);
            yield return null;
        }
        transform.position = start + Vector3.right * 10;
    }
}

 

 위의 CoMoveForSeconds는 time만큼의 시간동안 오른쪽으로 10유닛만큼 움직이게 한다. 만약 해당 코드를 Update안에 만들었을 경우 시간이 다 될 때 까지 얼어버리겠지만, 코루틴은 yield return을 사용할 수 있다. yield return null이 되면 코루틴은 실행을 멈춘 뒤, 유니티에게 실행권을 돌려주고 유니티는 다음 프레임이 되면 코루틴을 해당 위치부터 다시 시작시킨다. 그렇기에 자신의 루틴과 유니티의 루틴이 공존할 수 있다. 이를 이용해 몇가지 예를 만들어 보자.

 

 

1. 코루틴을 1초 간격으로 실행시키기

 MoveForSeconds에 따라 열심히 움직여줄 상자 3개와 상자 3개를 묶어 1초마다 실행시키는 MoveMaster을 만들었다.

 

public class MoveMaster : MonoBehaviour
{
    public MoveForSeconds[] objs;

    public void StartMove()
    {
        StartCoroutine(CoMove());
    }

    IEnumerator CoMove()
    {
        foreach (MoveForSeconds obj in objs)
        {
            StartCoroutine(obj.CoMoveForSeconds());
            yield return new WaitForSeconds(1.0f);
        }
    }
}

 

 상자는 각각 2초, 3초, 4초 동안 오른쪽으로 움직이게 설정했다. 코루틴의 다음 부분이 언제 실행될지는 yield return 뒤에 값에 따라 설정할 수 있다. null을 반환하면 다음 프레임에 바로 실행되고, WaitForSeconds(float)을 만들어 반환하면 해당 시간 만큼 지난 뒤 실행된다.

 

 

2. 다른 코루틴의 종료 뒤 실행시키기

 만약 코루틴을 시간 간격이 아닌 특정 코루틴이 끝난 뒤 실행시키고 싶다면 WaitForSeconds 대신 다른 코루틴을 리턴하면 된다. 코루틴을 반환할 경우 해당 코루틴의 종료 시점에 맞추어 정지 지점부터 다시 실행된다. 이를 이용해 앞의 코루틴을 앞의 상자가 다 움직이면 다음 상자가 움직이게 바꾸어보자.

 

IEnumerator CoMove()
{
    foreach (MoveForSeconds obj in objs)
    {
        yield return StartCoroutine(obj.CoMoveForSeconds());
    }
}

 

 

 

3. 최소 3초를 기다린 뒤 실행시키기

 StartCoroutine은 해당 코루틴을 관리할 수 있는 Coroutine을 반환하고 이를 변수에 할당해 유연하게 활용 가능하다. 예를 들어 다음 상자가 움직일 때 최소 3초의 시간 뒤에 움직이게 할 수 있다.

 

IEnumerator CoMove()
{
    foreach (MoveForSeconds obj in objs)
    {
        Coroutine coroutine = StartCoroutine(obj.CoMoveForSeconds());
        yield return new WaitForSeconds(3.0f);
        yield return coroutine;
    }
}

 

 

'유니티와 놀기' 카테고리의 다른 글

delegate 사용하기  (0) 2023.04.04
간단한 단색 그래픽 만들기  (0) 2023.03.05
체스말을 잡기  (0) 2022.11.04
체스말을 움직이기  (0) 2022.11.01