이전에 Addressables쪽 코드를 그냥 Task를 이용해서 비동기 코드를 구현했는데, 이 부분을 UniTask로 고쳐보기로 했다.
현재 프로젝트에 적용하기
이전 코드
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.ResourceManagement.AsyncOperations;
public enum UIPrefabs
{
Alert,
Confirm,
StageButton,
StageContainer,
}
/// <summary>
/// UI 프리팹을 로드하고, 인스턴스화된 객체와 Addressables 핸들을 매핑하여 관리합니다.
/// </summary>
public class UIPrefabManager : MonoBehaviour
{
public static UIPrefabManager Instance { get; private set; }
private Dictionary<GameObject, AsyncOperationHandle<GameObject>> activePrefabHandles =
new Dictionary<GameObject, AsyncOperationHandle<GameObject>>();
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
public async Task<GameObject> ShowUI(UIPrefabs address)
{
AsyncOperationHandle<GameObject> loadHandle = ResourceLoader.LoadAssetAsync<GameObject>(address.ToString());
await loadHandle.Task;
if (loadHandle.Status == AsyncOperationStatus.Succeeded)
{
GameObject prefabAsset = loadHandle.Result;
Transform uiParent = FindObjectOfType<Canvas>().transform;
GameObject instance = ObjectPool.Get(prefabAsset, uiParent);
activePrefabHandles.Add(instance, loadHandle);
return instance;
}
else
{
ResourceLoader.Release(loadHandle);
return null;
}
}
public void CloseUI(GameObject instance)
{
if (activePrefabHandles.TryGetValue(instance, out AsyncOperationHandle<GameObject> handle))
{
ObjectPool.Release(instance);
ResourceLoader.Release(handle);
activePrefabHandles.Remove(instance);
}
else
{
Destroy(instance);
}
}
}
해당 코드에서 단점들이 좀 보였는데,
-
FindObjectOfType로 사용해서 Canvas를 찾고 있는데, 만약 잦은 호출이 발생한다면 성능 저하가 있는 메서드 이다.
-
await 이후에 loadHandle.Status를 확인해서 에러를 처리하고 있는데, try-catch문을 이용하는 방식이 더 깔끔하다.
코드 개선하기
Canvas 찾는 방식 변경
| UIPrefabManager |
|---|
 |
| UICanvasMarker |
|---|
 |
- 현재 메인 캔버스를 등록하는 메서드를 만들어서 각 씬에 캔버스에서 메서드를 호출하는 방식으로 캔버스 문제를 해결했다.
try-catch문으로 변경
| 이전 ShowUI |
|---|
 |
| 개선한 ShowUI |
|---|
 |
- 이전 ShowUI에서는 냅다 호출과 대기를 하고 성공 여부를 판단함.
- 개선된 ShowUI에서는 호출에서 오류가 발생하면 바로 catch문에서 오류를 판별한다.
테스트
| 테스트 |
|---|
 |
- Adressables로 불러오는 파일의 크기가 크지 않아서 그런지, UniTask Tracker에 찍히진 않았다.