1. 리소스 메니저 생성 2. 풀 매니저 생성 3. 조이스틱 생성 - 조이스틱 이미지 잘 움직이는것도 확인 함 To-Do 1. 조이스틱과 플레이어 캐릭터를 연결하는 로직 2. 몬스터 이동 로직을 고민해서 구현해보기
177 lines
5.1 KiB
C#
177 lines
5.1 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class PoolManager : IManager
|
|
{
|
|
#region Pool
|
|
/// <summary>
|
|
/// 개별 오브젝트 풀.
|
|
/// </summary>
|
|
class Pool
|
|
{
|
|
// 이 풀이 관리하는 오브젝트의 원본 프리팹 경로
|
|
private string _path;
|
|
// 이 풀의 오브젝트들을 담아둘 부모 Transform
|
|
public Transform Root { get; private set; }
|
|
|
|
// 비활성화된 오브젝트(재고)를 담아두는 스택
|
|
private Stack<GameObject> _poolStack = new Stack<GameObject>();
|
|
|
|
/// <summary>
|
|
/// 풀 초기화
|
|
/// </summary>
|
|
public void Init(string path, int count)
|
|
{
|
|
_path = path;
|
|
GameObject original = Manager.Resource.Load<GameObject>(_path);
|
|
if(original == null)
|
|
{
|
|
Debug.LogError($"Pool Init Failed! Original prefab not found at path: {_path}");
|
|
return;
|
|
}
|
|
|
|
Root = new GameObject() { name = $"{original.name}_Root" }.transform;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
Push(Create(original));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 새 오브젝트 생성. Poolable 컴포넌트를 추가하고 경로를 지정.
|
|
/// </summary>
|
|
private GameObject Create(GameObject original)
|
|
{
|
|
GameObject go = Object.Instantiate(original);
|
|
go.name = original.name;
|
|
go.AddComponent<Poolable>().Path = _path;
|
|
return go;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 다 쓴 오브젝트를 풀에 반납 (비활성화 후 스택에 추가)
|
|
/// </summary>
|
|
public void Push(GameObject go)
|
|
{
|
|
if (go == null) return;
|
|
|
|
go.transform.SetParent(Root);
|
|
go.SetActive(false);
|
|
_poolStack.Push(go);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 풀에서 오브젝트를 꺼냄 (재고가 있으면 재고 사용, 없으면 새로 생성)
|
|
/// </summary>
|
|
public GameObject Pop(Transform parent)
|
|
{
|
|
GameObject go;
|
|
|
|
if (_poolStack.Count > 0)
|
|
{
|
|
go = _poolStack.Pop();
|
|
}
|
|
else
|
|
{
|
|
// 풀이 비었을 경우, 새로 5개를 생성하여 풀에 추가합니다.
|
|
GameObject original = Manager.Resource.Load<GameObject>(_path);
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
Push(Create(original));
|
|
}
|
|
// 이제 풀이 채워졌으니, 하나를 꺼내서 사용합니다.
|
|
go = _poolStack.Pop();
|
|
}
|
|
|
|
go.SetActive(true);
|
|
|
|
|
|
// @DontDestroyOnLoad 해제 부
|
|
// if(parent == null)
|
|
// poolable.transform.parent = Managers.Scene.CurrentScene.transform;
|
|
|
|
go.transform.SetParent(parent);
|
|
|
|
return go;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
// 모든 풀들을 관리하는 딕셔너리. <프리팹 경로, 풀>
|
|
private Dictionary<string, Pool> _pools = new Dictionary<string, Pool>();
|
|
private Transform _root;
|
|
|
|
/// <summary>
|
|
/// PoolManager 초기화. @Pool_Root 오브젝트 생성.
|
|
/// </summary>
|
|
public void Init()
|
|
{
|
|
if (_root == null)
|
|
{
|
|
_root = new GameObject { name = "@Pool_Root" }.transform;
|
|
Object.DontDestroyOnLoad(_root);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 게임 시작 시 미리 풀을 생성해 둠.
|
|
/// </summary>
|
|
public void CreatePool(string path, int count = 5)
|
|
{
|
|
if (_pools.ContainsKey(path))
|
|
{
|
|
Debug.LogWarning($"Pool already exists for path: {path}");
|
|
return;
|
|
}
|
|
|
|
Pool pool = new Pool();
|
|
pool.Init(path, count);
|
|
pool.Root.SetParent(_root);
|
|
_pools.Add(path, pool);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 풀에서 오브젝트를 꺼내 사용.
|
|
/// </summary>
|
|
public GameObject Pop(string path, Transform parent = null)
|
|
{
|
|
// 요청한 풀이 없으면 새로 1개짜리 풀을 생성
|
|
if (!_pools.ContainsKey(path))
|
|
{
|
|
CreatePool(path, 1);
|
|
}
|
|
|
|
return _pools[path].Pop(parent);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 사용이 끝난 오브젝트를 풀에 반납.
|
|
/// </summary>
|
|
public void Push(GameObject go)
|
|
{
|
|
// 오브젝트의 Poolable 컴포넌트에서 원본 경로를 찾아냄
|
|
string path = go.GetComponent<Poolable>()?.Path;
|
|
if (string.IsNullOrEmpty(path) || !_pools.ContainsKey(path))
|
|
{
|
|
Debug.LogWarning("Push failed! Check if object is poolable or if pool exists.");
|
|
Object.Destroy(go);
|
|
return;
|
|
}
|
|
|
|
// 경로에 맞는 풀에 오브젝트를 반납
|
|
_pools[path].Push(go);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 풀의 오브젝트들을 파괴하고 풀 목록을 초기화.
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
foreach (Transform child in _root)
|
|
{
|
|
GameObject.Destroy(child.gameObject);
|
|
}
|
|
_pools.Clear();
|
|
}
|
|
} |