System - ResourceManager

최강산·2023년 8월 3일
0

클래스 설명

Class ResourceManager

  • 리소스를 로드하거나 로드 된 리소스들을 생성, 삭제 등 관리하는 역할을 한다.

  • 리소스 로드는 Addressable을 사용한다.

  • using UnityEngine.AddressableAssets;

  • using Object = UnityEngine.Object;

먼저 Managers 스크립트에 ResourceManager를 추가한다.
(추가하는 방법은 Link :: System - Managers 페이지 참조)






로직설명

LoadAsync :: Addressable 호출을 위한 준비 작업과 호출

로드 호출 코드 :: LoadAsync<T>(string,Action<T> = null)
- T 자리의 반환 받을 객체의 형, string에 어드레서블을 호출할 key 값을 넣어준다.
private void LoadAsync<T>(string _key, Action<T> _callback = null) where T : Object
{
    //없다면 키로 어드레서블 loadasync를 하는데, 만약 키에 .sprite가 있다면 스프라이트를 뺌
    string loadkey = _key;
    if (_key.Contains(".sprite"))
    {
        loadkey = $"{_key}{_key.Replace(".sprite","")}";
    }

    //최종적인 key를 가지고 로드 후 로드 된 값을 딕셔너리에 넣고 콜백
    var asyncOperation = Addressables.LoadAssetAsync<T>(loadkey);
    asyncOperation.Completed += (op) => 
    {
        if(!dictionary_Resources.ContainsKey(_key))
            dictionary_Resources.Add(_key, op.Result);
        _callback?.Invoke(op.Result as T);
    };
}

private

  • LoadAsync 함수 호출

  • Key 값을 검사 후 호출 될 값이 예외처리 되는 값인이 체크

  • 예외처리가 되는 값이라면 그 값에 맞는 Key 값으로 변경

  • Key를 넣어 Addressable 호출

  • 로드 된 값을 Dictionary 안에 넣고 관리

  • 콜백이 있다면 로드 된 값을 콜백






CheckLoaded :: 이미 로드 된 값만을 리턴

로드 호출 코드 :: CheckLoaded<T>(string)
- T 자리의 반환 받을 객체의 형, string에 어드레서블을 호출할 key 값을 넣어준다.
private T CheckLoaded<T>(string _key) where T : Object
{
    if (dictionary_Resources.TryGetValue(_key, out Object resource))
    {
        return resource as T;
    }

    //만약 스프라이트라면 키를 바꿔서 저장했으니까 스프라이트인지 확인한 후 
    if (typeof(T) == typeof(Sprite))                      
    {
        _key = _key + ".sprite";
        if (dictionary_Resources.TryGetValue(_key, out Object sprite))
        {
            return sprite as T;
        }
    }
    return null;
}

private

  • CheckLoaded 함수 호출

  • Key 값으로 Dictionary에 이미 있는지 체크 후 있다면 값 반환 후 종료

  • 없다면 예외처리가 되어 있는지 체크 후 예외 처리에 맞는 Key 값으로 변경

  • 바뀐 Key 값으로 Dictionary에 있는지 체크 후 있다면 값 반환

  • 없다면 null 반환






Load :: 체크, 로드 자동화

체크, 로드 호출 코드 :: Managers.Resource.Load<T>(string,Action<T> = null)
- T 자리의 반환 받을 객체의 형, string에 어드레서블을 호출할 key 값을 넣어준다.
public void Load<T>(string _key, Action<T> _callback = null) where T : Object
{
    T ob = CheckLoaded<T>(_key);

    if (ob != null)
    {
        _callback?.Invoke(ob as T);
        return;
    }

    LoadAsync<T>(_key, (_ob) =>
    {
        _callback?.Invoke(_ob as T);
    });
}
  • Load 함수 호출

  • 이미 값이 로드 되어 있는지 체크

  • 로드 되어 있다면 콜백 후 종료

  • 로드 되어 있지 않다면 로드 후 콜백






LoadAllAsynk :: 한 묶음 로드

한 묶음 호출 코드 :: Managers.Resource.LoadAllAsynk<T>(string, Action<string,int,int> = null)
- T 자리의 반환 받을 객체의 형, string에 어드레서블을 호출할 key 값을 넣어준다.
public void LoadAllAsynk<T>(string _label, Action<string,int,int> _callback = null) where T : Object
{
    var operationHandle = Addressables.LoadResourceLocationsAsync(_label, typeof(T));

    operationHandle.Completed += (op) => 
    {
        int currentLoadCount = 0;
        int totalLoadCount = op.Result.Count;

        foreach (var result in op.Result)
        {
            LoadAsync<T>(result.PrimaryKey, (ob) => 
            {
                currentLoadCount++;
                _callback?.Invoke(result.PrimaryKey, currentLoadCount, totalLoadCount);
            });
        }
    };
}
  • LoadAllAsynk 함수 호출

  • Key 값을 통해 Addressable을 호출

  • 호출 된 모든 값들을 Dictionary에 등록

  • 콜백이 있다면 현재 로드 된 리소스 이름과 로드 된 리소스의 개수, 총 로드할 리소스의 개수를 콜백






Instantiate :: 로드 된 오브젝트 생성

로드 오브젝트 생성 호출 코드 :: Managers.Resource.Instantiate(string, Transform = null)
- string에 리소스 key 값을 넣어준다.
public GameObject Instantiate(string _key, Transform _parent = null)
{
    GameObject po = Managers.Pool.Get(_key);
    if (po != null)
    {
        po.transform.SetParent(_parent);
        return po;
    }

    GameObject prefab = CheckLoaded<GameObject>($"{_key}");
    if (prefab == null)
    {
        Debug.LogError("프리팹이 로드되어 있지 않음, 로드 하셈");
        return null;
    }

    GameObject go = GameObject.Instantiate(prefab);
    go.name = prefab.name;
    go.transform.SetParent(_parent);
    return go;
}
  • Instantiate 함수 호출

  • Pool이 이미 존재하는지 PoolManager.Get 함수를 사용해서 체크

  • Pool이 존재한다면 Get 반환 값 반환 후 종료

  • 아닐 경우 로드 되어 있는지 체크

  • 로드 되어 있지 않다면 에러 코드 출력, null 값 반환 후 종료

  • 로드 되어 있다면 그 값으로 생성, 초기화 후 반환






Destroy :: 상황에 맞는 오브젝트 삭제, 비활성화

한 묶음 호출 코드 :: Managers.Resource.Destroy(GameObject)
- T 자리의 반환 받을 객체의 형, string에 어드레서블을 호출할 key 값을 넣어준다.
public void Destroy(GameObject _go)
{
    if (_go == null) return;
    if (Managers.Pool.Push(_go)) return;

    Object.Destroy(_go);
}
  • Destroy 함수 호출

  • GameObject 값이 없으면 리턴

  • GmaeObject 값의 풀이 있는지 PoolManager.Push 함수를 통해 체크

  • 있다면 종료

  • 없다면 삭제






시도

Load 기능 분리 및 자동화

  • 기존 교수님께 받은 코드는 각각 기능이 나누어져 있고 성공과 실패로 나누어져 있었음

  • 생각해보면 따로 로드만 할 거면 없으면 자동으로 생성되는 코드도 있으면 좋을 것 같다는 생각

  • 그래서 체크 후 있을 때, 없을 때에 맞는 자동화 함수 생성

profile
나 왜 아직도 초보 개발자?

2개의 댓글

comment-user-thumbnail
2023년 8월 3일

잘 봤습니다. 좋은 글 감사합니다.

1개의 답글

관련 채용 정보