Practice_Unity/Assets/Scripts/Managers/ResourceManager.cs
Seonkyu.kim 60d64f1069 작업
1. UI - 조이스틱 UIManager에 추가 및 Scene에서 호출 방식 변경
2. UI - 경험치 바 앞에 레벨 아이콘 추가
3. 몬스터 죽었을때 경험치로 변경
4. 경험치 바와 레벨 아이콘 연동

Todo
1. 투사체 공격 만들기
2. 몬스터가 플레이어 쫓아오게 만들기
3. 몬스터를 카메라 외각에서 다량으로 생성하는 기능 추가하기
4. 몬스터가 캐릭터 공격시 체력 닳게 하기
5. 메뉴 UI 만들기
6. 레벨업시 획득 스킬 UI 만들기
7. 체력바 UI 만들기
8. 공격시 데미지 띄우는 UI 만들기
2025-10-02 17:37:10 +09:00

94 lines
3.7 KiB
C#

using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 구상
/// 1. 리소르 로드 작업은 비용이 큰 작업이기에 한 번 로드한 리소스는 딕셔너리에 저장해 필요시 재활용 : 캐싱
/// 2. 경로를 받아 리소스를 로드해 Instantiate를 실행해 생성된 게임 오브젝트를 반환
/// 3. 생성된 게임 오브젝트를 파괴
/// </summary>
public class ResourceManager: IManager
{
private Dictionary<string, Object> _resources = new Dictionary<string, Object>();
public T Load<T>(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<T>(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<GameObject>(path);
if (original == null)
{
Debug.LogError($"ResourceManager Instantiate Failed! Prefab not found at path: {path}");
return null;
}
// 2. 프리팹에 Poolable 컴포넌트가 있는지 확인
if (original.GetComponent<Poolable>() != 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를 통해 리소스를 불러오게 된다면 비용이 큰 작업이기에 성능 저하가 발생할 수 있다.
/// 즉 리소스 매니저에서 캐싱 작업을 하는 이유는 프로젝트 전체의 리소스 관리를 효율적으로 하기 위함이다.