UNITY

[UNITY] 코루틴(Coroutine) 사용하기

멍정 2022. 5. 10. 16:13
코루틴은 실행을 일시 중지하고 Unity에 제어 권한을 반환한 후 다음 프레임에서 중단했던 위치에서 계속할 수 있는 함수와 같습니다.
-Unity 매뉴얼

간단하게 말하자면 리턴을 하는 시점에서 리턴값(시간)만큼 멈췄다가 시간이 지나고 다시 호출되면 멈췄던 부분에서 다시 실행한다. 

일반적인 반복문 같은 경우는 빠르게 실행되기 때문에 점진적인 변화를 시각적으로 제공할 수 없다.

하지만 코루틴은 return부분에서 타임 딜레이를 넣을 수 있어서 변화를 시각적으로 체감할 수 있다.

 

코루틴을 사용하는 기본적인 방법은 StartCoroutine(함수명); 을 통해 호출한다.

private void Start()
    {
        StartCoroutine(함수명);
    }

    IEnumerator 함수명()
    {
    	yield return new WaitForSeconds(시간);
    }

yield return 은 여러 가지를 반환할 수 있다.

null 한 프레임을 기다린다.
WaitForSeconds() 넣어준 시간만큼 기다린다 ex)WaitForSeconds(5f); //5초 대기
-> TimeScale에 영향을 받는다.
WaitForSecondsRealtime() 실제 시간만큼 기다린다. 
-> TimeScale에 영향을 받지 않는다.

코루틴을 사용할 때 주의할 점은 스크립트가 들어있는 오브젝트가 setActive(false)등으로 비활성화되면 작동하지 않는다는 점이다.

 

이번에는 식물의 성장을 표현하고자 무한루프에 코루틴을 넣어봤다.

start에 코루틴을 넣고 코루틴 내부에서 무한루프를 돌리면 계속 실행되는 모습을 볼 수 있다.

 

우선 변화해야하는 식물의 크게 2종류라서 tag값으로 종류를 나누고 그 내부에서 SetActive로 변화를 줬다.

 private void Start()
    {
        StartCoroutine(vinylgreenhouse());
    }

    IEnumerator vinylgreenhouse()
    {
        while(true) //무한루프
        {
            if (gameObject.tag == "CropType1") //3개 이상의 종류로 변화함
            {
                for (int i = 2; i < gameObject.transform.childCount; i++)
                {
                    yield return new WaitForSeconds(5f);
                    transform.GetChild(i).gameObject.SetActive(true);
                    Debug.Log(transform.GetChild(i).gameObject.name);
                }
                for (int t = 2; t < gameObject.transform.childCount; t++)
                {
                    yield return new WaitForSeconds(5f);
                    transform.GetChild(t).gameObject.SetActive(false);
                }
            }
            else if (gameObject.tag == "CropType2") //2개의 오브젝트가 켜졌다 꺼졌다를 반복함
            {
                if (transform.GetChild(1).gameObject.activeSelf == true)
                {
                    yield return new WaitForSeconds(5f); //8640000
                    transform.GetChild(1).gameObject.SetActive(false);
                    transform.GetChild(2).gameObject.SetActive(true);
                }
                else
                {
                    yield return new WaitForSeconds(5f);
                    transform.GetChild(1).gameObject.SetActive(true);
                    transform.GetChild(2).gameObject.SetActive(false);
                }
            }
        }
    }

기껏 움짤도 만들었는데 화질이 왜이럴까..

실행하면 설정해준 5초에 맞춰서 코루틴함수가 실행하는 것을 볼 수 있다.

CropType1

 

CropType2

자료 참고 : https://www.youtube.com/watch?v=ahji9F5hJJ4&t=362s https://docs.unity3d.com/kr/2020.3/Manual/Coroutines.html