- 원격에서의 에셋 로드 과정을 이해한다
- 과정 1 : 초기화
- 과정 2 . 카탈로그
- 과정 3 .에셋 번들의 다운로드
- 과정 4 .에셋 로드
[ 어드레서블 에셋 원격 로드의 과정 ]
1 . 어드레서블 에셋 원격 로드
[ 어드레서블이 원격에서 에세을 로드하는 과정 ]
- 에셋 로드 메서드 중 하나를 호출하면 어드레서블 시스템은 다음 작업을 수행하는 비동기 작업을 시작한다 .
- IResourceLocation 키를 제외하고 지정된 키에 대한 리소스 위치를 조회 .
- 종속성 목록을 수집 .
- 필요한 원격 에셋 번들을 다운로드 .
- 에셋 번들을 메모리에 로드 .
- 작업의 Result 오브젝트를 로드된 오브젝트로 설정 .
- 작업의 Status를 업데이트하고 Completed 이벤트 리스너를 호출 .
- 로드 작업이 성공하면 Status가 Succeeded로 설정되고, 로드된 오브젝트는 Result 오브젝트에서 액세스할 수 있다. .
오류가 발생하면 예외가 작업 오브젝트의 OperationException 멤버에 복사되고 Status가 Failed로 설정된다.
[ 1 . 초기화 ]
1 . 초기화 작업
[ 초기화 ]
- 어드레서블 시스템은 어드레서블을 처음 로드하거나 어드레서블 API를 호출할 때 런타임에 자체적으로 초기화된다.
- 어드레서블을 더 일찍 초기화하려면 Addressables.InitializeAsync를 호출한다.
- 초기화가 이미 발생한 경우 이 메서드는 아무 작업도 수행하지 않는다.
[ 초기화의 과정 ]
초기화 작업에서는 다음과 같은 작업을 수행한다.
- ResourceManager 및 ResourceLocators를 설정.
- StreamingAsset에서 어드레서블이 생성하는 설정 데이터를 로드한다 .
- 초기화 오브젝트 작업을 실행한다 .
- 콘텐츠 카탈로그를 로드한다. 기본적으로 어드레서블은 먼저 콘텐츠 카탈로그의 업데이트를 확인하고 사용 가능한 경우 새 카탈로그를 다운로드한다 ( 카탈로그 관리가 자동인 경우).
[ 초기화 동작의 변경 ]
다음 어드레서블 설정으로 초기화 동작을 변경할 수 있다.
- Only update catalogs manually: 어드레서블이 업데이트된 카탈로그를 자동으로 확인하지 않는다. 카탈로그 수동 업데이트에 대한 자세한 내용은 카탈로그 업데이트를 참조하자.
- Build Remote Catalog: 어드레서블이 원격 카탈로그 없이 원격 콘텐츠를 로드하려고 하지 않는다.
- Custom certificate handler: 원격 에셋 호스팅 서비스에 액세스하기 위해 커스텀 인증서 핸들러가 필요한 경우 이를 식별한다.
- Initialization object list: 초기화 작업 중에 어드레서블이 호출하는 IObjectInitializationDataProvider 스크립터블 오브젝트를 애플리케이션에 추가한다.
2 . 초기화 오브젝트
[ 초기화 오브젝트란 ]
- 어드레서블 에셋 설정에 오브젝트를 연결하여 런타임에 초기화 프로세스에 전달할 수 있다.
- 예시중 하나로 CacheInitializationSettings 오브젝트를 생성하여 Unity의 Cache 설정을 런타임에 초기화할 수 있다.
- 고유한 유형의 초기화 오브젝트를 생성하려면 IObjectInitializationDataProvider 인터페이스를 구현하는 스크립터블 오브젝트를 생성한다.
- 이 오브젝트를 사용하여 어드레서블이 런타임 데이터와 함께 포함하는 ObjectInitializationData 에셋을 생성할 수 있다.
[ CacheInitializationSettings ]
CacheInitializationSettings 오브젝트를 사용하여 Unity의 Cache 설정을 런타임에 초기화할 수 있다 .
- CacheInitializationSettings 에셋을 생성한다(메뉴: Assets > Addressables > Initialization > Cache Initialization Settings).
- 프로젝트 패널에서 새 에셋 파일을 선택하여 인스펙터에서 설정을 확인한다.
- 설정을 원하는 대로 조정한다.
- 어드레서블 설정 인스펙터(메뉴: Window > Asset Management > Addressables > Settings)를 연다.
- 인스펙터의 Initialization Objects 섹션에서 + 버튼을 클릭하여 목록에 새 오브젝트를 추가한다.
- File 다이얼로그에서 CacheInitializationSettings 에셋을 선택하고 Open 을 클릭한다.
- 캐시 설정 오브젝트가 목록에 추가된다 .
런타임에 어드레서블이 초기화되면 이 설정이 기본 Unity Cache에 적용된다.
- 이 설정은 어드레서블 시스템에서 다운로드한 에셋 번들뿐만 아니라 기본 캐시에 있는 모든 에셋 번들에 적용된다.
- CacheDirectoryOverride : 캐시에 대한 사용자 정의 디렉터리를 지정한다
- CompressionEnabled : 압축을 활성화하면 디스크 공간을 절약할 수 있지만 압축을 푸는 동안 성능에 영향을 미칠 수 있다.
- ExpirationDelay : 에셋이 제거되기 전까지 캐시에 남아 있는 기간을 제어하려면 이 기능을 사용한다. 기본 150일 .
- LimitCacheSize : 캐시 크기를 제한할지 여부를 나타냅니다.
- MaximumCacheSize : 디스크 공간을 너무 많이 소모하지 않도록 최대 캐시 크기를 정의한다 .
추가후 아무런 동작도 하지 않는다면 추가하지 않은것과 같은 기본값이다 .
[ 2 . 카탈로그 확인 ]
1 . 런타임의 카탈로그 관리
[ 카탈로그의 관리 ]
- 기본적으로 어드레서블 시스템은 런타임에 카탈로그를 자동으로 관리한다.
- 원격 카탈로그를 사용했다면 어드레서블 시스템은 자동으로 새 카탈로그를 확인 , 새 버전을 다운로드해 메모리에 로드한다 .
2 . 카탈로그 수동으로 관리하기
[ 카탈로그의 수동 관리 ]
- 카탈로그의 확인 및 업데이트를 수동으로 해야하는 경우 다음의 처리가 필요하다 .
- 어드레서블 세팅에서 Only update catalogs manually를 체크한다 . 이제 카탈로그는 수동으로 관리된다 .
[ 카탈로그의 수동 관리 ]
IEnumerator CheckCatalogs()
{
List<string> catalogsToUpdate = new List<string>();
AsyncOperationHandle<List<string>> checkForUpdateHandle
= Addressables.CheckForCatalogUpdates();
checkForUpdateHandle.Completed += op => { catalogsToUpdate.AddRange(op.Result); };
yield return checkForUpdateHandle;
if (catalogsToUpdate.Count > 0)
{
AsyncOperationHandle<List<IResourceLocator>> updateHandle
= Addressables.UpdateCatalogs(catalogsToUpdate);
yield return updateHandle;
Addressables.Release(updateHandle);
}
Addressables.Release(checkForUpdateHandle);
}
- 위 스크립트로 업데이트할 카탈로그가 있다면 업데이트를 시행한다
[ 3 . 에셋 번들 다운로드 ]
1 . 에셋 번들 캐싱하기
[ 어에셋 번들의 캐싱 ]
- 그룹의 Use Asset Bundle Cache가 활성화된 경우 , 그룹에서 빌드된 에셋 번들은 다운로드후 클라이언트 기기에 캐시된다 .
- 캐시된 번들은 업데이트 혹은 캐시에서 삭제된 경우에만 다시 다운된다 .
[ 불필요한 캐시 삭제하기 ]
- 기기에 불필요한 캐시 데이터가 있는 경우 다음 옵션 중 하나를 선택할 수 있다.
- 전체 번들 캐시를 삭제하려면 Caching.ClearCache를 사용합니다.
- 더 이상 참조되지 않는 캐시 엔트리를 제거하려면 Addressables.CleanBundleCache를 사용한다. 이 함수는 일반적으로 어드레서블을 초기화한 후(어드레서블 초기화 커스터마이징 참조) 또는 추가 카탈로그를 로드한 후(런타임에 카탈로그 관리 참조) 호출한다 .
- 카탈로그를 업데이트한 후 자동으로 Addressables.CleanBundleCache를 호출하려면 Addressables.UpdateCatalogs에서 autoCleanBundleCache 파라미터를 사용한다 .
[ 종속성 미리 로드하기 ]
IEnumerator IEDownloadAsset()
{
AsyncOperationHandle operationHandle = Addressables.DownloadDependenciesAsync("default");
State = eState.Downloading;
yield return operationHandle;
AssetBundle.UnloadAllAssetBundles(true);
Addressables.Release(operationHandle);
yield return IELoadMemory();
}
- 위 메서드는 default 레이블을 가진 에셋이 있는 종속성 (에셋번들등 )을 미리 로드하여 성능을 개선 할 수 있다 .
- 게임을 처음 시작할 때 필수 콘텐츠를 다운로드하여 사용자가 게임플레이 도중 콘텐츠 다운로드를 기다릴 필요가 없다.
- 번들 다운로드후 구버전의 에셋 번들을 메모리에서 언로드한다 .
[ 4 . 어드레서블 에셋 로드 ]
1 . 어드레서블 에셋 로드
[ 에셋 로드 키 ]
- 단일 키 또는 키 목록을 로드 메서드에 전달함으로 로드할 에셋을 식별한다 .
- 키는 다음 오브젝트 중 하나가 될 수 있다 .
- Address : 에셋에 할당된 주소가 포함된 문자열
- Label : 하나 이상의 에셋에 할당된 레이블을 포함하는 문자열
- Asset Referecne 오브젝트 : Asset Reference 의 인스턴스
- IResourceLocation 인스턴스 : 에셋 및 그 종속성을 로드하는 방법을 설명하는 중간객체
2 . 어드레서블이 에셋을 로드하는 방법
[ 에셋 로드 과정 ]
- IResourceLocation 키를 제외하고 지정된 키에 대한 리소스 위치를 조회한다 .
- 종속성 목록을 수집한다
- 필요한 원격 에셋 번들을 다운로드 한다 .
- 에셋 번들을 메모리에 로드한다
- 작업의 Result 오브젝트를 로드된 오브젝트로 설정한다 .
- 작업의 Status을 업데이트하고 Completed 이벤트 리스너를 호출한다 .
3 . 로드된 에셋과 키 연결하기
[ 에셋 로드 과정 ]
- 개별 에셋을 로드하는 순서는 로드 메서드에 전달하는 목록의 키 순서와 다를 수 있다 .
- 만약 에셋을 로드할때 키와 에셋을 연결해야 한다면 다음의 단계를 거칠 수 있다 .
- 에셋 키 목록을 사용 , IResourceLocatoin 인스턴스를 로드한다 .
- IResourceLocation 인스턴스를 키로 사용하여 개별 에셋을 로드한다 .
- 아래 예시는 IResourceLocation 오브젝트는 키 정보를 포함 , 키와 에셋을 연관시키기 위해 Dictionary를 사용한다 .
[ 키워드 ]
- AsyncOperationHandle : 비동기 작업을 나타내는 Unity의 Addressables 시스템에서 제공하는 구조체. 비동기 작업의 진행 상황과 완료를 추적하는 데 사용됨 . 다음의 정보가 포함된다 .
- Status: 작업의 현재 상태(예: None, Succeeded, Failed )
- IsDone: 작업이 완료되었는지 여부를 나타내는 부울
- Result: 작업이 성공적으로 완료된 경우 작업의 결과
- Completed: 구독할 수 있는 이벤트로, 작업이 완료되면 호출
- IResourceLocation : Addressables 시스템에서 리소스의 위치를 나타내는 인터페이스.다음의 정보가 포함된다 .
- PrimaryKey: 리소스를 식별하는 데 사용되는 키.
- InternalId: 리소스 위치에 대한 내부 식별자
- ProviderId: 리소스를 로드할 공급자의 ID
- Dependencies: 이 리소스가 의존하는 다른 리소스 위치의 목록
- ResourceType: 리소스 유형(예: Texture2D, AudioClip).
- CreateGenericGroupOperation :여러 비동기 작업을 관리할 수 있는 그룹 작업을 생성한다 . 이를 통해 여러 비동기 작업을 단일 단위로 처리할 수 있으므로 동시에 여러 작업 완료를 더 쉽게 조정하고 처리할 수 있다.
[ 스크립트 ]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
internal class LoadWithLocation : MonoBehaviour
{
//에셋 로드후 키 - 핸들이 담기는 딕셔너리
public Dictionary<string, AsyncOperationHandle<Texture2D>> operationDictionary;
//로드에 사용할 키 . 레이블로 설정하였다 .
public List<string> keys=new List<string> { default,"Data"};
//모든 에셋 로드가 완료되면 실행할 이벤트
public UnityEvent Ready;
IEnumerator LoadAndAssociateResultWithKey(IList<string> keys)
{
if (operationDictionary == null)
operationDictionary = new Dictionary<string, AsyncOperationHandle<Texture2D>>();
//지정된 키에 대한 리소스 위치를 로드하는 비동기 작업
AsyncOperationHandle<IList<IResourceLocation>> locations
= Addressables.LoadResourceLocationsAsync(keys,
Addressables.MergeMode.Union, typeof(Texture2D));
yield return locations;
var loadOps = new List<AsyncOperationHandle>(locations.Result.Count);
//locations를 순환하며 에셋을 비동기적으로 로드
foreach (IResourceLocation location in locations.Result)
{
AsyncOperationHandle<Texture2D> handle =
Addressables.LoadAssetAsync<Texture2D>(location);
handle.Completed += obj => operationDictionary.Add(location.PrimaryKey, obj);
loadOps.Add(handle);
}
// 비동기작업을 그룹으로 관리
yield return Addressables.ResourceManager.CreateGenericGroupOperation(loadOps, true);
Ready.Invoke();
}
void Start()
{
Ready.AddListener(OnAssetsReady);
StartCoroutine(LoadAndAssociateResultWithKey(keys));
}
private void OnAssetsReady()
{
float x = 0, z = 0;
foreach (var item in operationDictionary)
{
Debug.Log($"{item.Key} = {item.Value.Result.name}");
////Instantiate(item.Value.Result,
//// new Vector3(x++ * 2.0f, 0, z * 2.0f),
//// Quaternion.identity, transform);
//if (x > 9)
//{
// x = 0;
// z++;
//}
}
}
private void OnDestroy()
{
// 에셋이 필요하지 않을때 해제
foreach (var item in operationDictionary)
{
Addressables.Release(item.Value);
}
}
}
'유니티 > Addressable' 카테고리의 다른 글
[ Addressable ] 06 . 콘텐츠 원격으로 배포하기 (0) | 2024.08.01 |
---|---|
[ Addressable ] 05 . Addressable 콘텐츠 업데이트 하기 (2) | 2024.07.19 |
[ Addressable ] 04 . Addressable 콘텐츠 빌드하기 (0) | 2024.07.18 |
[ Addressable ] 03 . Addressable 그룹으로 관리하기 (0) | 2024.07.12 |
[ Addressable ] 02 . Addressable 로 프로젝트 전환하기 (0) | 2024.07.10 |