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 기능 분리 및 자동화
기존 교수님께 받은 코드는 각각 기능이 나누어져 있고 성공과 실패로 나누어져 있었음
생각해보면 따로 로드만 할 거면 없으면 자동으로 생성되는 코드도 있으면 좋을 것 같다는 생각
그래서 체크 후 있을 때, 없을 때에 맞는 자동화 함수 생성
잘 봤습니다. 좋은 글 감사합니다.