유니티에서 코루틴을 다루다 보면 WaitforSecond나 WaitUntil같이 일정 시간, 혹은 일정 조건까지 기다리게 하는 대기문을 사용하는 경우가 잦습니다.
'몇 초간 기다려라' 혹은 '무엇이 어떻게 될 때까지 기다려라' 외에도 '이 코루틴이 끝날 때까지 기다려라'라는 대기 조건도 있는데,
마지막의 경우는 yield return startcoroutine()으로 구현할 수 있습니다.
이번에는 여러 코루틴을 받아올 때마다 선입선출 방식으로 하나하나 실행하게 하는 스크립트를 만들어보겠습니다.
public class TempManager : MonoBehaviour
{
private static TempManager instance = null;
public static TempManager Instance { get { return instance; } }
private void Awake() => instance = this; //임시 싱글톤 생성
private Queue<IEnumerator> CoroutineQueue= new Queue<IEnumerator>(); //코루틴 목록
private Queue<string> CoroutineNames= new Queue<string>(); //표시용 이름 목록
public void AddCoroutineQueue(IEnumerator cor,string name) //대기열에 코루틴 삽입
{
CoroutineQueue.Enqueue(cor);
CoroutineNames.Enqueue(name);
UpdateQueueText(); //큐에 코루틴과 이름을 넣고 디버그용 이름 목록 초기화
if (WorkingCoroutine == null) //대기열 코루틴이 작동하고 있지 않다면
{ //새로 코루틴을 시작
WorkingCoroutine = WorkingQueue();
StartCoroutine(WorkingCoroutine);
}
}
private IEnumerator WorkingCoroutine = null;
private IEnumerator WorkingQueue()
{
while (CoroutineQueue.Count > 0) //큐가 남아있는 한 반복
{
yield return StartCoroutine(CoroutineQueue.Dequeue());//대기열 하나 완료하면
CoroutineNames.Dequeue(); //대기열 이름도 할당 해제
UpdateQueueText();
yield return null;
}
WorkingCoroutine = null; //큐가 전부 동나면 코루틴 할당 해제
}
[SerializeField] private TextMeshProUGUI QueueText = null; //디버그 이름 출력용
private void UpdateQueueText()
{
var _list = CoroutineNames.ToList();
StringBuilder _stb= new StringBuilder();
for(int i=0;i< _list.Count;i++)
{
_stb.Append(_list[i]);
if(i<_list.Count-1)_stb.Append("<br>");
}
QueueText.text = _stb.ToString();
}
}
public class test : MonoBehaviour //상하좌우 이동 코루틴을 전달
{
[SerializeField] private Transform MovingObj = null;
public void Click_up()=> TempManager.Instance.AddCoroutineQueue(moveobj(Vector2.up),"move_up");
public void Click_right() => TempManager.Instance.AddCoroutineQueue(moveobj(Vector2.right), "move_right");
public void Click_down() => TempManager.Instance.AddCoroutineQueue(moveobj(Vector2.down), "move_down");
public void Click_left() => TempManager.Instance.AddCoroutineQueue(moveobj(Vector2.left), "move_left");
private IEnumerator moveobj(Vector2 dir)
{
float _speed = 3.0f;
float _time = 0.0f;
while (_time < 1.0f)
{
MovingObj.Translate(dir * _speed*Time.deltaTime);
_time += Time.deltaTime;
yield return null;
}
}
}
버튼을 눌러 이동 코루틴을 전달할 때마다 큐에 해당 코루틴이 누적되고,
선입선출 방식으로 이동 명령을 하나하나 다 소화시키고 있습니다.
이를 활용해 각종 UI의 조작 결과를 겹치지 않고 순차적으로 연결되듯이 만들 수도 있습니다.
'C#,Unity' 카테고리의 다른 글
| Unity - Google Spreadsheet 연동하기(실시간X) (0) | 2024.05.13 |
|---|---|
| Unity - 부드럽게 순차적으로 이동시키기 (0) | 2024.05.13 |
| Unity - Coroutine을 변수로 사용하기 (0) | 2024.05.09 |
| Unity UI - 화면을 벗어나지 않은 UI 만들기 (0) | 2024.05.08 |
| Unity - 오디오 싱글톤으로 사운드 관리한 기록 (0) | 2024.05.07 |