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 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를 통해 리소스를 불러오게 된다면 비용이 큰 작업이기에 성능 저하가 발생할 수 있다. /// 즉 리소스 매니저에서 캐싱 작업을 하는 이유는 프로젝트 전체의 리소스 관리를 효율적으로 하기 위함이다.