using UnityEngine; using System; using System.Collections; /// /// 오브젝트를 관리하는 클래스 (오브젝트 풀) /// public class ObjectManager : MonoBehaviour { public static ObjectManager Instance { get; private set; } #region member /// /// 프리팹을 오브젝트 풀에 등록 한다 /// [Serializable] public class ObjectPoolEntry { /// /// 인스턴스를 생성하기 위한 프리팹 /// [SerializeField] public GameObject Prefab; /// /// 생성되는 프리팹 갯수 /// [SerializeField] public int Count; [HideInInspector] public GameObject[] pool; [HideInInspector] public int objectsInPool = 0; } #endregion /// /// 지정한 양 만큼 처리 하도록 버퍼를 생성 /// public ObjectPoolEntry[] Entries; /// /// 사용되지 않고 있는 풀링된 객체를 관리 하는 컨테이너 /// protected GameObject ContainerObject; void OnEnable() { Instance = this; } // Use this for initialization void Start() { ContainerObject = new GameObject("ObjectPool"); // 프리랩을 반복하여 새로운 목록을 확인 for (int i = 0; i < Entries.Length; i++) { ObjectPoolEntry objectPrefab = Entries[i]; // 임시 저장될 오브젝트를 생성 objectPrefab.pool = new GameObject[objectPrefab.Count]; // 임시 저장될 오브젝트에 프리랩들을 채운다 for (int n = 0; n < objectPrefab.Count; n++) { GameObject newObj = (GameObject)Instantiate(objectPrefab.Prefab); newObj.name = objectPrefab.Prefab.name; PoolObject(newObj); } } } /// /// 스트링으로 풀링된 객체를 가져온다 /// /// /// 스트링으로 찾은 객체 /// /// /// 가져올 객체 /// /// /// true 면 객체가 풀링 되어있으면 반환한다. /// public GameObject GetObjectForType(string objectType, Vector3 pos, Quaternion rot, bool onlyPooled = true) { for (int i = 0; i < Entries.Length; i++) { GameObject prefab = Entries[i].Prefab; if (prefab.name != objectType) continue; if (Entries[i].objectsInPool > 0) { GameObject pooledObject = Entries[i].pool[--Entries[i].objectsInPool]; pooledObject.transform.parent = null; pooledObject.transform.position = pos; pooledObject.transform.rotation = rot; pooledObject.SetActive(true); return pooledObject; } else if (!onlyPooled) { GameObject obj = (GameObject)Instantiate(Entries[i].Prefab); obj.name = obj.name + "_not_pooled"; return obj; } } return null; } /// /// 스트링으로 풀링된 객체를 가져온다 /// then null will be returned. /// /// /// 스트링으로 찾은 객체 /// /// /// 가져올 객체 /// /// /// true 면 객체가 풀링 되어있으면 반환한다. /// public GameObject GetObjectForType(string objectType, Vector2 pos, bool onlyPooled = true) { for (int i = 0; i < Entries.Length; i++) { GameObject prefab = Entries[i].Prefab; if (prefab.name != objectType) continue; if (Entries[i].objectsInPool > 0) { GameObject pooledObject = Entries[i].pool[--Entries[i].objectsInPool]; pooledObject.transform.parent = null; pooledObject.transform.position = pos; pooledObject.SetActive(true); return pooledObject; } else if (!onlyPooled) { GameObject obj = (GameObject)Instantiate(Entries[i].Prefab); obj.name = obj.name + "_not_pooled"; return obj; } } return null; } /// /// 객체를 다시 풀링 한다 /// /// /// 풀링할 객체 /// public void PoolObject(GameObject obj) { for (int i = 0; i < Entries.Length; i++) { if (Entries[i].Prefab.name != obj.name) continue; obj.SetActive(false); obj.transform.parent = ContainerObject.transform; if (obj.rigidbody != null) { obj.rigidbody.velocity = Vector3.zero; } Entries[i].pool[Entries[i].objectsInPool++] = obj; return; } Destroy(obj); } }