예제코드 링크 : https://github.com/Eunji-new/async_TestCode_unity
참조 링크(참조 내용을 바탕으로 코드를 제작하였습니다.) : https://kangworld.tistory.com/25
4개 오브젝트의 애니메이션이 동기/비동기적으로 작동되게하는 프로그램이다.
다음과 같이 테스트할 수 있도록 구성하였다.
- 1번키 입력 : 코루틴 이용
- 2번키 입력 : Async-Await 사용(하지만 사실상 동기 프로그래밍)
- 3번키 입력 : Async-Await 사용 비동기 프로그래밍
private async void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
MovingItems_Coroutine();
Debug.Log("MovingItems_Couroutine가 시작된 후(MovingItems_Couroutine는 진행중이다)");
}
else if (Input.GetKeyDown(KeyCode.Alpha2))
{
await MovingItems_Async_v1();
Debug.Log("MovingItems_Async_v1 끝난 후에 발생하는 로그(사실상 비동기)");
}
else if (Input.GetKeyDown(KeyCode.Alpha3))
{
await MovingItems_Async_v2();
Debug.Log("MovingItems_Async_v2 끝난 후에 발생하는 로그");
}
}
3개의 키를 누를 때 실행되는 함수 내부코드는 다음과 같다.
/*
코루틴을 이용
각 아이템에 맞는 오브젝트 애니메이션 함수를 실행한다.
함수가 끝나는 것을 기다리지않고, 코루틴의 yield문 마다 다음구문이 진행될 수 있도록 넘겨준다.
*/
public void MovingItems_Coroutine()
{
foreach (var item in currentItems)
{
StartCoroutine(PlayAnim_Coroutine(item));
}
}
/*
async-await 이용(사실상 동기 프로그래밍)
각 아이템에 맞는 오브젝트 애니메이션 함수를 실행하고
실행한 함수가 끝날때까지 기다린다.
*/
public async Task MovingItems_Async_v1()
{
foreach (var item in currentItems)
{
if (item.name.Contains("Cube"))
await MoveCube();
else if (item.name.Contains("Sphere"))
await MoveSphere();
else if (item.name.Contains("Cylinder"))
await MoveCylinder();
else
await MoveCapsule();
Debug.Log($"{item.name} 애니메이션 끝남 ");
}
}
/*
async-await 이용한 비동기 프로그래밍
각 아이템에 맞는 오브젝트 애니메이션 함수를 실행하고
실행한 함수가 종료될 때, 해당 함수가 끝났다는 로그를 띄운다.
함수가 끝나는 것을 기다리지않고, 다른 함수들도 같이 실행된다.
*/
public async Task MovingItems_Async_v2()
{
var t0 = MoveCube();
var t1 = MoveSphere();
var t2 = MoveCylinder();
var t3 = MoveCapsule();
List<Task> taskList = new List<Task> { t0, t1, t2, t3 };
while (taskList.Count > 0)
{
//먼저 끝난 Task를 받아서 처리한다.
Task finishedTask = await Task.WhenAny(taskList);
if (finishedTask == t0)
{
Debug.Log("cube 애니메이션 끝남");
}
else if (finishedTask == t1)
{
Debug.Log("Sphere 애니메이션 끝남");
}
else if (finishedTask == t2)
{
Debug.Log("Cylinder 애니메이션 끝남");
}
else if (finishedTask == t3)
{
Debug.Log("Capsule 애니메이션 끝남");
}
taskList.Remove(finishedTask);
}
}
애니메이션을 실질적으로 Play하는 함수는 다음과 같다.
각 오브젝트 애니메이션 실행 함수에 시간 초를 두어서 차이를 더 쉽게 알도록 구성해보았다.
public IEnumerator PlayAnim_Coroutine(GameObject obj)
{
GetItemAnim(obj).Play();
int seconds = 0;
if (obj.name.Contains("Cube"))
seconds = 1;
else if (obj.name.Contains("Sphere"))
seconds = 2;
else if (obj.name.Contains("Cylinder"))
seconds = 3;
else
seconds = 4;
yield return new WaitForSeconds(seconds);
if (obj.name.Contains("Cube"))
Debug.Log("cube 애니메이션 끝남");
else if (obj.name.Contains("Sphere"))
Debug.Log("sphere 애니메이션 끝남");
else if (obj.name.Contains("Cylinder"))
Debug.Log("cylinder 애니메이션 끝남");
else
Debug.Log("capsule 애니메이션 끝남");
}
public Animation GetItemAnim(GameObject obj)
{
return obj.GetComponent<Animation>();
}
#region Move Animation
public async Task MoveCube()
{
if (!currentItems[0]) return;
GetItemAnim(currentItems[0]).Play();
await Task.Delay(1000);
}
public async Task MoveSphere()
{
if (!currentItems[1]) return;
GetItemAnim(currentItems[1]).Play();
await Task.Delay(2000);
}
public async Task MoveCylinder()
{
if (!currentItems[2]) return;
GetItemAnim(currentItems[2]).Play();
await Task.Delay(3000);
}
public async Task MoveCapsule()
{
if (!currentItems[3]) return;
GetItemAnim(currentItems[3]).Play();
await Task.Delay(4000);
}
#endregion
1번 결과 : 코루틴 이용
2번 결과 : async 동기 프로그래밍
3번 결과 : async이용 비동기 프로그래밍
결과를 보다시피 코루틴이든 async이든 프로그래밍 결과는 같다.
(async 비동기 프로그래밍은 async 함수가 끝날때까지 await 또 기다리게 되어서 굳이 따지자면 코루틴이 더 비동기스럽다. - await도 안쓰면 똑같겠지만,,,)
유니티에는 이미 코루틴이라는 유용한기능이 있기때문에 Async를 사용하고 쓰레드를 하나 추가해면서까지 비동기를 구현하는 것은 여러모로 비추천이라고 한다.
하지만 코루틴에서 무한 루틴을 만들거나 서버에서 무수한 데이터를 받아오는 등 시간이 오래걸리는 작업에 사용하기에 유용하다. 여러모로 잘 참고해서 프로그램에 맞게 잘 사용하는 것이 좋겠다.
* 부족하거나 잘못된 내용이 있다면 댓글로 남겨주세요!
'유니티3D[Unity3D]' 카테고리의 다른 글
[Unity] WebGL 빌드 에러 : BuildFailedException: Incremental Player build failed! (0) | 2023.04.27 |
---|---|
[OpenCV For Unity] AR Glass에 OpenCV 기반 Image Tracking 구현 (0) | 2023.04.03 |
[Unity3D] GameObject와 애니메이션의 관계 + animation event 실행 안되는 이슈 (0) | 2022.10.28 |
Unity VFX Graph 안드로이드에서 사용 불가 이슈 (2) | 2022.09.19 |
Unity 버튼 OnClick 함수 안보이는 현상 해결법 (0) | 2022.07.04 |