백지부터 시작하는 이세계 코딩 생활

Coroutine, IEnumerator, yield return 본문

백지부터 시작하는 이세계 유니티 생활 since 2020

Coroutine, IEnumerator, yield return

조아덕 2020. 11. 17. 19:41
Coroutine

스레드(Threde) 처리 중 임의의 함수 ( IEnumerator ) 를 끼워넣기 위해서 사용함. ( ie. 실행되던 함수 일시정지 )
유사 멀티스레드 효과가 필요할 때 사용할 수 있다.

임의의 특정 함수가 실행되고 있는 중에 StartCoroutine() 함수가 호출 되면 특정 함수의 작동이 일시정지 (제어권 양도) 되고 IEnumerator 함수를 찾아가게 된다. 이때 yield return [ ... ] ( 반환값 )코드를 만나면 호출되었던 위치로 돌아가 StartCoroutine() 이후의 작업을 완료하게 된다. StartCoroutine() 이후 작업이 완료되면, IEnumerator 함수 내의 yield return 이후를 처리하게 된다.

 

특징

* 프로세스가 Multi threade 와 유사하게 작동한다.
* Update 문이나 timer 를 사용하지 않고도 원하는 작업을 수행시킬 수 있다.
* IEnumeratoryield return [ ... ] 문을 함께 사용해야 한다.
* Coroutine 함수가 호출 된 지점부터 코드가 재실행 된다.
* 재실행 될 때는 기존에 가지고 있던 정보들이 소멸되지 않은 채로 재실행 된다.
* 여러개의 진입지점 (Entry Point)을 가질 수 있다.
* Animation 효과를 동적할당( Code 부분에서 )으로 처리할 수 있다.
* using System.Collections.Generic 네임스페이스를 갖는다

 

사용요령 및 주의사항

* 오작동 없는 Coroutine 사용을 하기 위해서 StartCoroutine() 호출 전 StopCoroutine() 처리를 해준다.
* 사용되지 않는 Coroutine을 Stop 시켜 놓지 않으면 Memory leak (메모리 낭비) 현상이 발생하여 프로그램 퍼포먼스를 저해시킬 수 있다.  
* Coroutine의 parameter는 1개만 사용가능 하다. 만약 여러개를 사용해야 한다면 함수의 형태로 만들어서 사용한다.

public void TouchUp(BaseEventData _data)
    {
        StartCoroutine(nameof(R_SmoothStop));
        GameManager.Instance.cPlayer.playerTarget.CheckTarget();

    }

private IEnumerator R_SmoothStop()
    {
        Vector2 posStart = posCurrnet;
        Vector2 posEnd = Vector2.zero;
        float fper = 0.0f;
        float fspeed = 5.0f;

        while (posCurrnet.magnitude > 0.0f)
        {
            fper += Time.fixedDeltaTime * fspeed;            
            posCurrnet = Vector2.Lerp(posStart, posEnd, fper);
            yield return new WaitForFixedUpdate();
        }
    }

Ref. Memory leak : ko.wikipedia.org/wiki/%EB%A9%94%EB%AA%A8%EB%A6%AC_%EB%88%84%EC%88%98

 


ex) Object Targeting

연속실행 시 : 
여러 target object들이 존재할 때 player object와의 거리에 따라 가장 가까운 target object 를 선택하게 된다.
i.e. ) target의 실시간 거리 체크가 가능하며 따라서 aim이 수시로 바뀐다. 연속동작이 필요한 곳에 사용하면 좋다.
이때, Time.deltaTime 과 함께 사용하여 원하는 타이밍에 작동시킬 수 있다.

단일실행 시 : 
여러 target object들이 존재할 때 player object와의 거리가 실시간으로 변함에도 불구하고 처음 지정된 target과의 특정 이벤트가 완료되어야 다음 target을 지정하게 된다.

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

public class TestDescription : MonoBehaviour
{
    private SpriteRenderer spriteRenderer;

    // Start is called before the first frame update
    void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
        StartCoroutine("RunFadeOut");
        SubRoutine();
    }

    // Update is called once per frame
    void Update()
    {

    }

    private IEnumerator RunFadeOut()
    {
        Color color = spriteRenderer.color;
        while (color.a > 0.0f)
        {
            color.a -= 0.05f;
            spriteRenderer.color = color;
            yield return new WaitForSeconds(0.2f);
            print("alpha value => " + color);
        }
    }

    private void SubRoutine()
    {
        for (int i = 0; i < 5; i++)
        {
            print("this is SubRoutine Message" + i);
        }
    }
}

yield return [ ... ]

yield return 이후 사용하는 코드들.

add. 임의로 코루틴을 종료시키고 싶다면 yield break를 호출하면 된다.


 

코루틴(coroutine)은 루틴의 일종으로서, 협동 루틴이라 할 수 있다(코루틴의 "Co"는 with 또는 togather를 뜻한다). 상호 연계 프로그램을 일컫는다고도 표현가능하다. 루틴과 서브 루틴은 서로 비대칭적인 관계이지만, 코루틴들은 완전히 대칭적인, 즉 서로가 서로를 호출하는 관계이다.
코루틴들에서는 무엇이 무엇의 서브루틴인지를 구분하는 것이 불가능하다. 코루틴 A와 B가 있다고 할 때, A를 프로그래밍 할 때는 B를 A의 서브루틴으로 생각한다. 그러나 B를 프로그래밍할 때는 A가 B의 서브루틴이라고 생각한다. 어떠한 코루틴이 발동될 때 마다 해당 코루틴은 이전에 자신의 실행이 마지막으로 중단되었던 지점 다음의 장소에서 실행을 재개한다

 


Ref.

docs.unity3d.com/kr/530/Manual/Coroutines.html

 

유니티 - 매뉴얼: 코루틴(Coroutine)

게임 오브젝트 생성 및 삭제 특수 폴더와 스크립트 컴파일 순서 코루틴(Coroutine) 함수를 호출하면 반환값을 반환하기 전에 실행 완료됩니다. 즉, 함수에서 수행되는 작업은 하나의 프레임에서 수

docs.unity3d.com

m.blog.naver.com/PostView.nhn?blogId=pxkey&logNo=221296053953&proxyReferer=https:%2F%2Fwww.google.com%2F

 

유니티 코루틴(Coroutine)과 서브 루틴

안녕하세요. 창작자 픽케입니다.​우리가 어떤 작업을 처리하기 위해 필요한 함수(Function)를 호출하면, ...

blog.naver.com

theeye.pe.kr/archives/2725

 

Unity C# – Coroutine 알아보기 | 아이군의 블로그

유니티에서 사용되는 코루틴(Coroutine)은 왜 필요한가? 유니티에서 화면의 변화를 일으키기 위해서는 Update() 함수 내에서 작업을 하게 됩니다. 이 Update() 함수는 매 프레임을 그릴때마다 호출되며

theeye.pe.kr

 

Comments