AddressableAsset은 어떻게 언제 Asset들을 로드할지 컨트롤할 수 있게 만들어주는 기능이다
Scene에 오브젝트나 리소스들을 다 넣어놓으면 해당 Scene을 로드할때 그 오브젝트와 리소스들을 다 메모리에 불러와야하기에 Scene 로드에 시간이 많이 걸리게 된다. 그렇게 하기 보단 필요한것만 Scene에 넣고 그때그때 필요한건 필요할때 불러오는 방식으로 개발해야 Scene 로드에 많은 시간 소모를 겪지 않게 된다
1. Addressables 설치
PackageManager에 들어가 Unity Registry 탭에서 Addressables 를 검색하면 위 이미지와 같이 Addressables unity package가 나오는데 해당 패키지를 설치해주면 된다
2. 사용방법
먼저 상단 탭에서 Window > Asset Management > Addressables > Group으로 들어가 Addressables Group 창을 연다
창을 열면 위와 같이 Create Addressables Settings 버튼이 보일건데 해당 버튼을 눌러 Addressables Setting을 생성한다
생성하게 되면 위와 같이 창이 열리고 Default Local Group이 Default로 생성된다
이제 Addressables로 로드할 게임오브젝트를 Default Local Group 아래로 Drag & Drop 하여 해당 게임오브젝트를 Addressable 게임오브젝트로 생성한다
그렇게 하고 나면 해당 게임오브젝트의 Inspector에 보면 Addressable이 활성화 된것을 확인 할 수 있다
3. 코드 작성
이제 코드를 작성해 Addressable 로 설정된 에셋들을 가져와 보자
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
AsyncOperationHandle<GameObject> asyncOpeationHandle = Addressables.LoadAssetAsync<GameObject>("key value");
asyncOpeationHandle.Completed += AsyncOperationHandle_Completed;
private void AsyncOperationHandle_Completed(AsyncOperationHandle<GameObject> asyncOperationHandle)
{
if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded)
{
Instantiate(asyncOperationHandle.Result);
}
else
{
Debug.Log("Failed to load!");
}
};
Addressables.LoadAssetAsync<T> 함수를 호출해 불러오고자 하는 AddressableAsset을 파라미터로 넣어 해당 에셋을 불러온다
리턴 값은 AsyncOperationHandle<T> 타입의 값이다.
AsyncOperationHandle의 Completed 콜백함수에 콜백 함수를 할당하여 에셋이 Load 되었을때 함수를 호출할 수 있다
위 코드에선 에셋 로드가 성공 했을때 Instantiate() 함수로 해당 에셋을 불러오고 Instantiate안에는 AsyncOperationHandle 값의 Result로 넣어줘야 한다
위와 같이 코드를 짜도 괜찮지만 키값을 string으로 넣어주어야 하다보니 대소문자나 약간의 실수만 발생해도 에셋의 로드가 실패하게 된다 그러한 실패를 막기 위한 방법으로는 AssetReference로 직접 로드할 에셋을 할당하고 있다가 로드하는 방식이 있다
[SerializeField] private AssetReference assetReference;
assetReference.LoadAssetAsync<GameObject>.Completed += (asyncOperationHandle) => {
if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded)
{
Instantiate(asyncOperationHandle.Result);
}
else
{
Debug.Log("Failed to load!");
}
};
이렇게 하면 키값을 실수로 잘못 입력하는 휴먼에러로 인한 로드실패는 벌어지지 않게 된다
키 값 뿐만이 아니라 Label값으로도 에셋을 로드할 수 있다
[SerializeField] private AssetLabelReference assetLabelReference;
Addressables.LoadAssetAsync<GameObject>(assetLabelReference).Completed += (asyncOperationHandle) => {
if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded)
{
Instantiate(asyncOperationHandle.Result);
}
else
{
Debug.Log("Failed to load!");
}
};
앞서 키값으로 에셋을 로드하게 되면 키값을 실수로 입력하는 휴먼에러로 인해 에러가 발생할 수 있다 하였는데 이 방식에도 에러가 발생할 수 있는 위험요소가 하나 남아있으니 그건 LoadAssetAsync<T> 함수를 호출할때 타입 값을 잘못하면 에러가 발생할수 있다는 것이다
Addressable Asset으로 게임오브젝트만 넣을수 있는건 아니고 AudioClip, Sprite, Texture 등등 많은 것들이 있을수 있는데 다른 타입을 호출하면 에러가 발생한다
이런 실수를 하지 않게 하기 위해 특정 타입의 AssetReference 타입을 사용할 수 있다
AssetReferenceGameObject assetReferenceGameObject;
assetReferenceGameObject.LoadAssetAsync().Completed += (asyncOperationHandle) =>
{
if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded)
{
Instantiate(asyncOperationHandle.Result);
}
else
{
Debug.Log("Failed to load!");
}
};
위와같이 작성하면 타입 실수로 인한 에러는 없어지게 된다.
근데 위와 같이 GameObject인 경우에는 AssetReferenceGameObject를 사용하면 되지만 내가 만든 타입이라던가 만들어져있지 않은 타입의 경우에는 어떻게 해야할까?
그럴경우 내가 직접 클래스를 만들어 주면 된다
예를들어 오디오클립이 없다고 한다면 아래와 같이 내가 직접 클래스를 만들어주면 된다
[System.Serializable]
public class AssetReferenceAudioClip : AssetReferenceT<AudioClip>
{
public AssetReferenceAudioClip(string guid) : base(guid){ }
}
다음으로 Load한후 Load Complete 콜백이 호출된 후 Instantiate 하지 않고 한번에 할 수 있는 방법도 있다
이 방법을 사용하면 Load후 Complete 콜백 호출후 Instantiate 하는거 보다 조금 더 빠르게 Instantiate 할수 있다
assetReferenceGameObject.InstantiateAsync();
InstantiateAsync() 함수를 사용하면 한번에 Load와 Instantiate를 할 수 있다
마지막으로 Load를 했으니 unLoad를 하는 방법이다
UnLoad의 경우 ReleaseInstantiate() 함수를 사용하면 unload 할 수 있다
private GameObject spawnedGameObject;
// Load
assetReferenceGameObject.InstantiateAsync().Completed += (asyncOperation) => spawnedGameObject = asyncOperation.Result;
// UnLoad
assetReferenceGameObject.ReleaseInstance(spawnedGameObject);
'Unity' 카테고리의 다른 글
[Unity] AI Navigation System 사용방법 (8) | 2024.12.11 |
---|---|
[Unity] NavMesh Surface Bake를 했는데 Scene View에서 파란색 표면이 보이지 않는 이슈 (6) | 2024.12.11 |
[Unity] 특정 게임오브젝트 기준으로 카메라 움직이기 (2) | 2024.11.29 |
[Unity] 캔버스 랜더모드(Canvas RenderMode) (0) | 2024.11.22 |
Unity New InputSystem 사용방법 (0) | 2024.11.22 |