프로젝트를 진행하면서 내가 사용해야 될 리소스 매니저에 대해 공부를 진행했다.
어드레서블 에셋을 사용하게 될텐데, 이해도가 필요했다.
리소스 매니저는 리소스 로딩과 관리의 복잡성을 줄이기 위해 설계되었다. 특히, 어드레서블 에셋 시스템을 사용하여 리소스 로딩을 최적화하고, 필요에 따라 쉽게 리소스를 로드하거나 재사용할 수 있도록 하는 기능이 포함되어 있다. 비동기적 로딩 방식은 게임의 성능을 향상시키고, 사용자 경험을 개선하는 데 도움이 된다.
리소스 저장소:
dic: T
ype과 string을 키로, UnityEngine.Object를 값으로 하는 딕셔너리를 사용하여 자원을 저장한다.
이를 통해 특정 타입의 자원을 이름으로 관리하고 빠르게 접근할 수 있다.
ReferenceDic:
Type과 string을 키로, AssetReference를 값으로 하는 딕셔너리를 사용한다.
이는 어드레서블 에셋 시스템과 연동되어 자원을 관리한다.
리소스 로딩 메소드:
LoadPrefab< T >: 특정 경로에서 주어진 이름의 프리팹을 로드한다. 이미 로드된 자원은 dic에서 재사용된다.
LoadPrefabAll< T >: 주어진 경로의 모든 리소스를 로드하여 리스트로 반환한다.
어드레서블 에셋 로딩:
LoadAssetReferenceToDic< T >와 LoadToLabelAsync< T > 메소드는 어드레서블 에셋 시스템을 사용하여 특정 타입의 에셋을 비동기적으로 로드하고 ReferenceDic에 저장한다.
LoadAssetsToType< T >와 LoadAssetToType< T > 메소드는 ReferenceDic에 저장된 에셋을 로드하고, 로드된 에셋에 대해 특정 작업을 수행한다.
에셋 참조 반환:
ReturnAssetReference< T > 메소드는 주어진 이름의 AssetReference를 반환합니다.
using System.Collections.Generic;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine;
using System;
using UnityEngine.ResourceManagement.ResourceLocations;
using System.Threading.Tasks;
using System.Xml.Linq;
public class ResourceManager
{
private static ResourceManager _instance;
public static ResourceManager Instance { get { return _instance ?? (_instance = new ResourceManager()); } }
Dictionary<System.Type, Dictionary<string, UnityEngine.Object>> dic = new Dictionary<System.Type, Dictionary<string, UnityEngine.Object>>();
public Dictionary<Type, Dictionary<string,AssetReference>> ReferenceDic = new Dictionary<Type, Dictionary<string, AssetReference>>();
public T LoadPrefab<T> (string path, string name) where T : UnityEngine.Object
{
System.Type type = typeof(T);
if (!dic.ContainsKey(type))
{
dic.Add(type, new Dictionary<string, UnityEngine.Object>());
}
if (!dic[type].ContainsKey(name))
{
dic[type].Add(name, Resources.Load<T>(path));
}
return (T)dic[type][name];
}
public List<T> LoadPrefabAll<T>(string path) where T : UnityEngine.Object
{
List<T> returnList = new List<T>();
var resources = Resources.LoadAll(path);
foreach (T resource in resources)
{
returnList.Add(resource);
}
return returnList;
}
// LoadAssetReferenceToDic<T>(), LoadToLabelAsync<T>() 는 AssetReference
public async Task LoadAssetReferenceToDic <T>()
{
Type type = typeof(T);
if (!ReferenceDic.ContainsKey(type))
{
ReferenceDic.Add(type, new Dictionary<string, AssetReference>());
}
await LoadToLabelAsync<T>();
}
public async Task LoadToLabelAsync<T>()
{
var asyncOperationHandle = Addressables.LoadResourceLocationsAsync(typeof(T).Name);
await asyncOperationHandle.Task;
if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded)
{
foreach (IResourceLocation location in asyncOperationHandle.Result)
{
string key = $"{typeof(T)}_{location.PrimaryKey}";
ReferenceDic[typeof(T)][key] = new AssetReference(location.PrimaryKey);
}
}
Addressables.Release(asyncOperationHandle);
}
public async Task LoadAssetsToType<T>(Action<T> action, Action completed = null)
{
foreach(var assetRefDic in ReferenceDic[typeof(T)])
{
await LoadAssetToType(assetRefDic.Value, action);
}
completed?.Invoke();
}
public async Task LoadAssetToType<T>(AssetReference asset, Action<T> action)
{
var handle = asset.LoadAssetAsync<T>();
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
action(handle.Result);
}
}
public AssetReference ReturnAssetReference<T>(string name)
{
return ReferenceDic[typeof(T)][name];
}
}
대본 수정
영상 촬영
기획 구체화