[TIL] Unity - ResourceManager - day 81

뭉크의 개발·2023년 11월 10일
0

Unity - Camp

목록 보기
50/70
post-thumbnail

🐧 들어가기 앞서

프로젝트를 진행하면서 내가 사용해야 될 리소스 매니저에 대해 공부를 진행했다.

어드레서블 에셋을 사용하게 될텐데, 이해도가 필요했다.


🐧 기억할 것 & 진행

리소스 매니저는 리소스 로딩과 관리의 복잡성을 줄이기 위해 설계되었다. 특히, 어드레서블 에셋 시스템을 사용하여 리소스 로딩을 최적화하고, 필요에 따라 쉽게 리소스를 로드하거나 재사용할 수 있도록 하는 기능이 포함되어 있다. 비동기적 로딩 방식은 게임의 성능을 향상시키고, 사용자 경험을 개선하는 데 도움이 된다.

리소스 저장소:

  • 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];
    }
}

🐧 내일 할 일

대본 수정

영상 촬영

기획 구체화

0개의 댓글