반응형
ObjectManager.cs
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// ObjectManager에서 관리할 오브젝트 리스트를 나타냅니다.
/// </summary>
public enum ObjectList {
Object1, Object2
}
/// <summary>
/// ObjectPool을 관리하는 클래스입니다.
/// </summary>
public class ObjectManager : MonoBehaviour
{
static ObjectManager instance = null;
public static ObjectManager Instance { // ObjectManager 싱글톤을 구현합니다. ObjectManager.Instance. 형식으로 접근합니다.
get {
if(instance == null){
instance = FindObjectOfType<ObjectManager>();
}
return instance;
}
}
[Header("Prefab")]
[SerializeField] GameObject object1_prefab = null;
Queue<GameObject> object1_queue = new Queue<GameObject>();
[SerializeField] GameObject object2_prefab = null;
Queue<GameObject> object2_queue = new Queue<GameObject>();
// 새로운 Prefab을 등록하는 단위
// [SerializeField] GameObject (오브젝트 이름)_prefab = null;
// Queue<GameObject> (오브젝트 이름)_queue = new Queue<GameObject>();
// ...
/// <summary>
/// 필요한 GameObject들을 미리 생성해 ObjectPool에 저장합니다.
/// </summary>
void Start() {
CreateObject(ObjectList.Object1, 5);
CreateObject(ObjectList.Object2, 10);
}
/// <summary>
/// Queue를 불러옵니다.
/// </summary>
/// <param name="object_target">불러올 오브젝트 Queue의 ObjectList입니다.</param>
Queue<GameObject> GetQueue(ObjectList object_target) {
try {
switch(object_target) {
case ObjectList.Object1 : return object1_queue;
case ObjectList.Object2 : return object2_queue;
default : throw new Exception("Queue가 존재하지 않습니다.");
}
} catch {
return null;
}
}
/// <summary>
/// Prefab을 불러옵니다.
/// </summary>
/// <param name="object_target">불러올 오브젝트 Prefab의 ObjectList입니다.</param>
GameObject GetPrefab(ObjectList object_target) {
try {
switch(object_target) {
case ObjectList.Object1 : return object1_prefab;
case ObjectList.Object2 : return object2_prefab;
default : throw new Exception("Prefab이 존재하지 않습니다.");
}
} catch {
return null;
}
}
/// <summary>
/// <para>GameObject를 생성합니다.</para>
/// <para>(처음 실행하거나 Queue에 가져올 GameObject가 없을 경우 이 메서드를 통해 새로운 GameObject를 생성합니다)</para>
/// </summary>
/// <param name="object_target">생성할 오브젝트의 ObjectList입니다.</param>
/// <param name="repeat">생성할 오브젝트의 개수입니다.</param>
void CreateObject(ObjectList object_target, byte repeat = 1) {
GameObject prefab_target = GetPrefab(object_target);
Queue<GameObject> queue_target = GetQueue(object_target);
if(prefab_target != null && queue_target != null) {
while(repeat-- > 0) {
GameObject object_new = Instantiate(prefab_target);
object_new.transform.SetParent(transform);
object_new.SetActive(false);
queue_target.Enqueue(object_new);
}
}
}
/// <summary>
/// <para>오브젝트를 불러옵니다.</para>
/// </summary>
/// <param name="object_target">불러올 오브젝트의 ObjectList입니다.</param>
/// <param name="setActive">불러올 오브젝트의 SetActive옵션입니다.</param>
public GameObject GetObject(ObjectList object_target, bool setActive = true) {
Queue<GameObject> queue_target = GetQueue(object_target);
if(queue_target != null) {
if(queue_target.Count <= 0) {
CreateObject(object_target);
}
GameObject object_return = queue_target.Dequeue();
object_return.transform.SetParent(null);
object_return.SetActive(setActive);
return object_return;
} else {
return null;
}
}
/// <summary>
/// <para>오브젝트를 반환합니다.</para>
/// </summary>
/// <param name="object_target">반환할 오브젝트의 ObjectList입니다.</param>
/// <param name="object_return">반환할 GameObject입니다.</param>
public void ReturnObject(ObjectList object_target, GameObject object_return) {
if(object_return) {
object_return.transform.SetParent(transform);
object_return.SetActive(false);
GetQueue(object_target).Enqueue(object_return);
} else {
throw new ArgumentNullException("반환하는 GameObject가 지정되지 않았습니다.");
}
}
}
다음과 같은 오브젝트 풀을 관리하는 스크립트를 작성합니다.
오브젝트 풀로 사용할 GameObject에 해당 스크립트를 추가하고 각 Prefab을 할당합니다.
Play 모드에 진입하면 오브젝트 풀이 활성화됩니다.
(오브젝트 풀에 있는 오브젝트들은 순환하면서 사용됩니다.)
Object 불러오기
GameObject object1 = ObjectManager.Instance.GetObject(ObjectList.Object1);
GetObject는 Instantiate대신 사용하는 GameObject 로드 메서드입니다.
(GameObject를 불러오고 나서 부모 오브젝트, 스케일, 위치 등은 직접적인 수정이 필요합니다.)
(UI(RectTransform) GameObject를 불러올때 반드시 transform.SetParent(... , false), transform.localScale = new Vector3(1f, 1f, 1f)를 해주어야 합니다.)
Object 반환하기
ObjectManager.Instance.ReturnObject(ObjectList.Object1, gameObject);
ReturnObject는 Destroy대신 사용하는 GameObject 삭제 메서드입니다.
(위의 경우 GameObject를 반환할때 gameObject의 ObjectList를 정확하게 지정해 주어야합니다.)
반응형