using System.Collections.Generic;
using UnityEngine;
///
/// 구상
/// 1. 리소르 로드 작업은 비용이 큰 작업이기에 한 번 로드한 리소스는 딕셔너리에 저장해 필요시 재활용 : 캐싱
/// 2. 경로를 받아 리소스를 로드해 Instantiate를 실행해 생성된 게임 오브젝트를 반환
/// 3. 생성된 게임 오브젝트를 파괴
///
public class ResourceManager: IManager
{
private Dictionary _resources = new Dictionary();
public T Load(string path) where T : Object
{
if (string.IsNullOrEmpty(path))
{
Debug.LogError("ResourceManager Load Failed! path is null or empty");
return null;
}
// 캐싱된게 있으면 그걸 반환
if (_resources.TryGetValue(path, out Object cachedResource)) return cachedResource as T;
// 새로 로드
T resource = Resources.Load(path);
if (resource == null)
{
Debug.LogError($"ResourceManager Load Failed! resource not found at path: {path}");
return null;
}
_resources.Add(path, resource);
return resource;
}
public GameObject Instantiate(string path, Transform parent = null)
{
// 1. 경로를 조합하여 원본 프리팹을 로드
GameObject original = Load(path);
if (original == null)
{
Debug.LogError($"ResourceManager Instantiate Failed! Prefab not found at path: {path}");
return null;
}
// 2. 프리팹에 Poolable 컴포넌트가 있는지 확인
if (original.GetComponent() != null)
{
// Poolable이 있으면 PoolManager를 통해 오브젝트를 가져옴
return Manager.Pool.Pop(path, parent);
}
// 3. Poolable이 없으면 직접 생성
GameObject go = Object.Instantiate(original, parent);
go.name = original.name;
return go;
}
public GameObject Instantiate(GameObject original, Transform parent = null)
{
// 3. Poolable이 없으면 직접 생성
GameObject go = Object.Instantiate(original, parent);
go.name = original.name;
return go;
}
public void Destroy(GameObject go, float delay = 0f)
{
if (go == null) return;
Object.Destroy(go,delay);
}
public void Clear()
{
_resources.Clear();
}
}
/// 리소스 매니저에서 캐싱 작업을 왜 하는가?
/// - 단순하게 호출하는 모든 생성작업이 어떠한 오브젝트의 풀링을 위한 것이라면 어차피 초기 한 번만 불려서 그 오브젝트를 재활용하면 되는데
/// 뭐하러 굳이 리소스를 딕셔너리로 남겨서 캐싱을 하나? 싶지만
/// 리소스 매니저의 역할은 풀링만을 위해 사용하는것이 아닌 프로젝트 전체의 리소스 관리를 위한 것이기에 풀링을 사용하지 않는 상황에서도 해당 리소스를 재활용할 수 있도록 하기 위함이다.
/// 예1. 가끔 씬에서 특정 오브젝트를 생성해야 하는 상황이 발생할 수 있다.
/// 예2. UI 매니저에서 특정 UI를 띄워야 하는 상황이 발생할 수 있다.
/// 예3. 서로 다른 스크립트가 같은 리소스를 필요로 할 수 있다.
/// - 이러한 상황에서 매번 Resources.Load를 통해 리소스를 불러오게 된다면 비용이 큰 작업이기에 성능 저하가 발생할 수 있다.
/// 즉 리소스 매니저에서 캐싱 작업을 하는 이유는 프로젝트 전체의 리소스 관리를 효율적으로 하기 위함이다.