풀링 매니저 생성 및 풀링 기능 구현

- 테스트 프리팹 삭제
This commit is contained in:
2026-02-07 02:58:55 +09:00
parent a404e684ed
commit 9cf290efca
12 changed files with 7530 additions and 726 deletions

View File

@@ -6,12 +6,14 @@ public class Managers : MonoBehaviour
static Managers Instance { get { Init(); return s_instance; } } // 유일한 매니저를 가져온다.
InputManager _input = new InputManager();
PoolManager _pool = new PoolManager();
ResourceManager _resource = new ResourceManager();
SceneManagerEx _scene = new SceneManagerEx();
SoundManager _sound = new SoundManager();
UIManager _ui = new UIManager();
public static InputManager Input { get { return Instance._input; } }
public static PoolManager Pool { get { return Instance._pool; } }
public static ResourceManager Resource { get { return Instance._resource; } }
public static SceneManagerEx Scene { get { return Instance._scene; } }
public static SoundManager Sound { get { return Instance._sound; } }
@@ -44,6 +46,7 @@ public class Managers : MonoBehaviour
DontDestroyOnLoad(go);
s_instance = go.GetComponent<Managers>();
s_instance._pool.Init();
s_instance._sound.Init();
}
}
@@ -54,5 +57,7 @@ public class Managers : MonoBehaviour
Input.Clear();
Scene.Clear();
UI.Clear();
Pool.Clear();
}
}

View File

@@ -0,0 +1,140 @@
using System.Collections.Generic;
using UnityEngine;
public class PoolManager
{
#region Pool
class Pool
{
public GameObject Original { get; private set; }
public Transform Root { get; set; }
Stack<Poolable> _poolStack = new Stack<Poolable>();
public void Init(GameObject original, int count = 5)
{
Original = original;
Root = new GameObject().transform;
Root.name = $"{original.name}_Root";
for (int i = 0; i < count; i++)
{
Push(Create());
}
}
Poolable Create()
{
GameObject go = Object.Instantiate<GameObject>(Original);
go.name = Original.name;
return go.GetOrAddComponent<Poolable>();
}
public void Push(Poolable poolable)
{
if (poolable == null)
{
return;
}
poolable.transform.parent = Root;
poolable.gameObject.SetActive(false);
poolable.IsUsing = false;
_poolStack.Push(poolable);
}
public Poolable Pop(Transform parent)
{
Poolable poolable ;
if (_poolStack.Count > 0)
{
poolable = _poolStack.Pop();
}
else
{
poolable = Create();
}
poolable.gameObject.SetActive(true);
// DontDestroyOnLoad 해제 용도
if (parent == null)
{
poolable.transform.parent = Managers.Scene.CurrentScene.transform;
}
poolable.transform.parent = parent;
poolable.IsUsing = true;
return poolable;
}
}
#endregion
Dictionary<string, Pool> _pool = new Dictionary<string, Pool>();
Transform _root;
public void Init()
{
if (_root == null)
{
_root = new GameObject { name = "@Pool_Root" }.transform;
Object.DontDestroyOnLoad(_root);
}
}
public void CreatePool(GameObject original, int count = 5)
{
Pool pool = new Pool();
pool.Init(original, count);
pool.Root.parent = _root;
_pool.Add(original.name, pool);
}
public void Push(Poolable poolable)
{
string name = poolable.gameObject.name;
if (_pool.ContainsKey(name) == false)
{
GameObject.Destroy(poolable.gameObject);
return;
}
_pool[name].Push(poolable);
}
public Poolable Pop(GameObject original, Transform parent = null)
{
if (_pool.ContainsKey(original.name) == false)
{
CreatePool(original);
}
return _pool[original.name].Pop(parent);
}
public GameObject GetOriginal(string name)
{
if (_pool.ContainsKey(name) == false)
{
return null;
}
return _pool[name].Original;
}
public void Clear()
{
foreach (Transform child in _root)
{
GameObject.Destroy(child.gameObject);
}
_pool.Clear();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b0bd1424e21567b40910e9ff8c3122f6

View File

@@ -0,0 +1,6 @@
using UnityEngine;
public class Poolable : MonoBehaviour
{
public bool IsUsing;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 215467617c5fd064188f16c055e8d51a

View File

@@ -4,27 +4,43 @@ public class ResourceManager
{
public T Load<T>(string path) where T : Object
{
if(typeof(T) == typeof(GameObject))
{
string name = path;
int index = name.LastIndexOf('/');
if (index >= 0)
{
name = name.Substring(index + 1);
}
GameObject go = Managers.Pool.GetOriginal(name);
if (go != null)
{
return go as T;
}
}
return Resources.Load<T>(path);
}
public GameObject Instantiate(string path, Transform parent = null)
{
GameObject prefab = Load<GameObject>($"Prefabs/{path}");
if (prefab == null)
GameObject original = Load<GameObject>($"Prefabs/{path}");
if (original == null)
{
Debug.Log($"Failed to load prefab : {path}");
return null;
}
GameObject go = Object.Instantiate(prefab, parent);
int index = go.name.IndexOf("(Clone)");
if (index >= 0)
if (original.GetComponent<Poolable>() != null)
{
// go.name = go.name.Substring(0, index);
go.name = go.name.Remove(index);
return Managers.Pool.Pop(original, parent).gameObject;
}
GameObject go = Object.Instantiate(original, parent);
go.name = original.name;
return go;
}
@@ -34,6 +50,14 @@ public class ResourceManager
{
return;
}
Poolable poolable = go.GetComponent<Poolable>();
if (poolable != null)
{
Managers.Pool.Push(poolable);
return;
}
Object.Destroy(go);
}
}

View File

@@ -9,6 +9,11 @@ public class GameScene : BaseScene
SceneType = Define.Scene.Game;
Managers.UI.ShowSceneUI<UI_Inven>();
for(int i = 0; i < 5; i++)
{
Managers.Resource.Instantiate("UnityChan");
}
}
public override void Clear()

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
@@ -7,7 +8,18 @@ public class LoginScene : BaseScene
{
base.Init();
SceneType = Define.Scene.Lobby;
SceneType = Define.Scene.Login;
List<GameObject> list = new List<GameObject>();
for(int i = 0; i < 5; i++)
{
list.Add(Managers.Resource.Instantiate("UnityChan"));
}
foreach (GameObject obj in list)
{
Managers.Resource.Destroy(obj);
}
}
private void Update()