<Coroutine 코루틴>
- Coroutine 개념
: 굉장히 큰 작업을 하나의 로직으로 해야할 때, 한번에 처리하기엔 너무 많은 시간이 든다.
-> 분할하여 작업하여 일정 시간 내에 끝내야 할 때 어떻게 처리해야하는가?
ex) 아래의 코드를 보면 일정 작업을 1000000 만큼 반복하여 진행하고 있다. 10000번씩 끊어서 실행시키고자 할때 어떻게 해야하는가?
void VeryComplicated()
{
for (int i = 0; i < 1000000; i++)
{
// 굉장히 힘든 작업
Debug.Log("Hello");
}
}
=> 일시 정지를 시킨 후 모든 상태를 복원된 상태로 시작을 할 수 있음
1. 다음과 같이 CoroutineTest class를 생성하여 실험해 본다.
CoroutineTest는 IEnumerable을 상속 받아서 인터페이스를 다음과 같이 정의하였다.
이때 yield를 붙여주어 return을 하면 다음과 같이 console창에 순서대로 1,2,3,4가 나오는 것을 확인할 수 있다.
*GameScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameScene : BaseScene
{
class CoroutineTest : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
}
protected override void Init()
{
base.Init();
// Scene Type setting
SceneType = Define.Scene.Game;
// TEMP
Managers.UI.ShowSceneUI<UI_Inven>();
// Coroutine Test
CoroutineTest test = new CoroutineTest();
foreach(int t in test)
{
Debug.Log(t);
}
}
// 해당 Scene이 종료됐을 때 날려줘야하는 것을 정의
public override void Clear()
{
}
}
2. 이때 test 를 int로 받아오지않고 var 형식으로 받아오면 GameObject 형식으로 반환한다. 위에서 한 것은 GameObject를 boxing하여 int형식으로 변환한 것이다.
3. 다음과 같이 Class를 반환하여도 값이 나오는 것을 확인할 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameScene : BaseScene
{
class Test
{
public int Id = 0;
}
class CoroutineTest : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new Test() { Id = 1 };
yield return new Test() { Id = 2 }; ;
yield return new Test() { Id = 3 }; ;
yield return new Test() { Id = 4 }; ;
}
}
protected override void Init()
{
base.Init();
// Scene Type setting
SceneType = Define.Scene.Game;
// TEMP
Managers.UI.ShowSceneUI<UI_Inven>();
// Coroutine Test
CoroutineTest test = new CoroutineTest();
foreach(System.Object t in test)
{
Test value = (Test)t;
Debug.Log(value.Id);
}
}
// 해당 Scene이 종료됐을 때 날려줘야하는 것을 정의
public override void Clear()
{
}
}
4. 그렇다면 Coroutine에서 완전히 멈추고 싶으면 yield break; 를 해줘야한다.
- 실제 적용
코루틴의 특징 정리
1. 함수의 상태를 저장/복원이 가능
-> 엄청 오래 걸리는 작업을 잠시 끊거나
-> 원하는 타이밍에 함수를 잠시 Stop/복원하는 경우
2. return -> 우리가 원하는 타입으로 가능(class도 가능)
어떻게 적용?
예를들어, 어떤 아이템을 만들어서 DB에 저장해야할 때 DB에 저장을 하고 응답을 받은 뒤에 다음 로직으로 넘어가야한다. -> 이때 잠시 멈추기 가능
시간관리에도 유용
: 4초 후에 Explore 된다고 할때 하나하나 매번 틱 마다 4초를 count하여 로직을 실행하는 것은 매우 휴율이 떨어진다.
-> 코루틴 유용
1. 4초를 기다린 후 로직을 실행하는 함수를 만들어보자. Coroutine 함수는 IEnumerator를 이용하여 만든다.
유니티 엔진 자체에 Coroutine을 사용한 WaitForSceconds라는 클래스를 return할 수 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameScene : BaseScene
{
protected override void Init()
{
base.Init();
// Scene Type setting
SceneType = Define.Scene.Game;
// TEMP
Managers.UI.ShowSceneUI<UI_Inven>();
StartCoroutine("ExplodeAfterSeconds", 4.0f);
}
IEnumerator ExplodeAfterSeconds(float seconds)
{
Debug.Log("Explode Enter");
yield return new WaitForSeconds(seconds);
Debug.Log("Explode Execute!!!");
}
// 해당 Scene이 종료됐을 때 날려줘야하는 것을 정의
public override void Clear()
{
}
}
다음과 같이 4초 후에 Explode Execute!! 가 console창에 뜨는 것을 알 수 있다.
2. 다음과 같이 새로운 코루틴을 작성하여 2초후에 모든 코루틴 작업을 취소 시킬 수 있다.
* GameScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameScene : BaseScene
{
Coroutine co;
protected override void Init()
{
base.Init();
// Scene Type setting
SceneType = Define.Scene.Game;
// TEMP
Managers.UI.ShowSceneUI<UI_Inven>();
Coroutine co = StartCoroutine("ExplodeAfterSeconds", 4.0f);
StartCoroutine("coStopExplode", 2.0f);
}
IEnumerator coStopExplode(float seconds)
{
Debug.Log("Stop Enter");
yield return new WaitForSeconds(seconds);
Debug.Log("Stop Execute!!");
if (co != null)
{
StopCoroutine(co);
co = null;
}
}
IEnumerator ExplodeAfterSeconds(float seconds)
{
Debug.Log("Explode Enter");
yield return new WaitForSeconds(seconds);
Debug.Log("Explode Execute!!!");
yield return null;
}
// 해당 Scene이 종료됐을 때 날려줘야하는 것을 정의
public override void Clear()
{
}
}
'Development > 유니티' 카테고리의 다른 글
[섹션8] Scene Manager #2 (0) | 2021.08.06 |
---|---|
[섹션8] Scene Manager (0) | 2021.08.06 |
[섹션7] 인벤토리 실습 & 코드 정리 (0) | 2021.08.01 |
[섹션 7] UI Manager (0) | 2021.07.30 |
[섹션7] UI - UI 자동화 (0) | 2021.07.29 |