오늘은 조금 화가 난 상태로 적는 부분인데..
회사에서 다른 회사들의 프로젝트들을 받아서
적용시키는 업무를 하고 있다.
정말 막장인 경우가 많은데,
아마 많은 초보 유니티 개발자들이 검색을 안해보고
모르는 그러한 부분일 수도 있어서 공유해보고자 한다.
바로 코루틴의 리턴값 받기다..
Unity6에 와서는 Awaitable이 신규로 생성되어서 좀 더 쉬워졌지만
아무래도 유니티의 아이덴티티는 코루틴이니까...
일례로 이런 코드를 받았다.
public bool CheckLocation()
{
StartCoroutine(Location());
while (CheckGPS)
{ }
...하략...
}
private bool CheckGPS = true;
IEnumerator Location()
{
CheckGPS = true;
...하략...
}
}
대충보면 의도는 느껴진다.
Location 코루틴이 다 돌고나서 함수의 밑에 부분이 실행되기를
원하는 것이다.
코루틴은 바로 지나가서 함수 밑을 실행시키므로
어이없게도 while문을 적어둔 것을 볼 수 있다.
이럴때 사용할 수 있는 것이 바로 Action이다.
소개하고 이후에 event Action등을 적어보도록 하겠다.
개요는 이러하다. 코루틴 안에서 모든 작업이 끝나는 것을 확인한 후
콜백을 호출하는 것이다.
그리고 코루틴을 실행한 함수에서는 이 콜백을 받고나면 이후의 작업들을 소화하는 것이다.
위의 코드를 수정하고나면 이렇다.
public bool CheckLocation()
{
// StartCoroutine(Location());
StartCoroutine(Location((result) => {
//하략의 내용들
}))
/* while문 제거 . 이제 CheckGPS는 필요가 없어진다.
while (CheckGPS)
{ }
*/
...하략...
}
private bool CheckGPS = true;
IEnumerator Location(Action onComplete)
{
CheckGPS = true;
...하략...
//작업이 다 끝났다면 Invoke호출
onComplete?.Invoke();
}
코드공개를 할 수 없어서 간단히 이렇게하였지만..
직접 간단히 짜보면 간단하다.
using System;
using System.Collections;
using UnityEngine;
public class ActionSample : MonoBehaviour
{
public void OnButton_Coroutine()
{
SampleCoroutine();
}
private void SampleCoroutine()
{
//string값을 리턴받아보자.
StartCoroutine(SampleCo("Test", (isComplete,onResult) =>
{
if (isComplete)
{
Debug.Log(onResult);
}
}));
}
private IEnumerator SampleCo(string sampleString, Action<bool,string> onComplete)
{
yield return new WaitForSeconds(2f);
onComplete?.Invoke(true,sampleString);
}
}
2초뒤에 우리가 적은 Test가 로그로 뜨는 것을 확인할 수 있다.
Action은 파라미터로 콜백을 받는 것 외에
리스너로 연결을 할 수도 있는데..
public Action<bool> onAction_test;
public event Action<bool> onAction_eventTest;
대표적으로 이 event가 붙고 안붙고의 2가지 경우가 있다.
큰 차이점이라고 한다면,
event가 붙으면 += -= 정도의 구독으로 밖에 사용을 못한다는 것이고
일반 Action은
public Action<bool> onAction_test;
public void TestAction(bool isOn)
{
onAction_test = (isOn) =>
{
if (isOn)
{
Debug.Log(isOn);
}
};
}
이런식으로..
자유롭게 사용할 수 있다.
물론 이 자유로움 때문에 어디에서든 호출/변경 할 수 있다는 위험이 존재한다.
그러니 왠만하면 event를 사용하여 구독으로 쓰도록 하는게 안전하다고 볼 수있겠다.
[SerializeField] private ActionSample _actionSample;
private void OnEnable()
{
_actionSample.onAction_test += JustBool;
_actionSample.onAction_eventTest += EventBool;
}
private void OnDisable()
{
_actionSample.onAction_test -= JustBool;
_actionSample.onAction_eventTest -= EventBool;
}
private void EventBool(bool isOn)
{
}
private void JustBool(bool isOn)
{
}
이런식으로 말이다.
일반 Action도 구독은 가능하니..
사실상 구독으로만 사용하는 습관을 들인다면 둘 중 무엇을 사용하든
크게 달라질 일은 없다고 볼 수 있겠다.
어쨌는 많은 사람들이 코루틴 콜백을 알게되어서
리턴값을 주는 방법을 익혔으면 좋겠다.
더 이상 처음같은 코드는 보고 싶은 생각이 없다..
'프로그래밍 > Unity' 카테고리의 다른 글
[유니티] Unity - ScriptableObject 잘 사용하기 (feat: json Editor) (0) | 2024.12.27 |
---|---|
[유니티] Unity - Parallel 병렬처리로 반복작업 속도 향상시키기 (0) | 2024.12.18 |
[유니티] Unity WebGL - React.js와 쌍방향 통신하기 (2) | 2024.12.11 |
[유니티] Unity - NewInputSystem 새로운 인풋시스템 적용하기. (0) | 2024.12.10 |
Unity - Rest API 만들고 적용하기 (0) | 2024.12.09 |