출처 : http://minhyeokism.tistory.com/23
모바일 프로젝트에서 필수적인 요소인 오브젝트 풀링.
총에서 총알이 나가는 예제를 활용하여 만든 소스가 잘되어 있는 것 같아 적어놓자.
풀링할 객체는 PoolableObject 클래스를 상속받아 사용하면 된다.
ObjectPool<T>.cs의
- ObjStack : 비활성화 된 object들을 담고있는 Stack(풀)
- ObjList : 활성화 된 object들을 담고있는 List(참조용)
// ObjectPool.cs using UnityEngine; using System.Collections; using System.Collections.Generic; public class ObjectPool where T : PoolableObject { private int allocateCount; public delegate T Initializer (); private Initializer initializer; private Stack objStack; public List objList; public ObjectPool () { // default constructor } public ObjectPool (int ac, Initializer fn) { this.allocateCount = ac; this.initializer = fn; this.objStack = new Stack (); this.objList = new List (); } public void Allocate () { for (int index = 0; index < this.allocateCount; ++index) { this.objStack.Push(this.initializer()); } } public T PopObject () { if (this.objStack.Count <= 0) { Allocate(); } T obj = this.objStack.Pop(); this.objList.Add(obj); obj.gameObject.SetActive(true); return obj; } public void PushObject (T obj) { obj.gameObject.SetActive(false); this.objList.Remove(obj); this.objStack.Push(obj); } public void Dispose () { if (this.objStack == null || this.objList == null) return; this.objList.ForEach(obj => this.objStack.Push(obj)); while (this.objStack.Count > 0) { GameObject.Destroy(this.objStack.Pop()); } this.objList.Clear(); this.objStack.Clear(); } } // PoolableObject.cs using UnityEngine; using System.Collections; using System.Collections.Generic; public class PoolableObject : MonoBehaviour { protected ObjectPool pPool; public virtual void Create (ObjectPool pool) { pPool = pool; gameObject.SetActive(false); } public virtual void Dispose () { pPool.PushObject(this); } public virtual void _OnEnableContents () { // to do ... } public virtual void _OnDisableContents () { // to do ... } } // ObjectPoolManager.cs using UnityEngine; using System.Collections; public class ObjectPoolManager : MonoBehaviour { private static ObjectPoolManager singleton; public static ObjectPoolManager GetInstance () { return singleton; } public ObjectPool bulletPool = new ObjectPool (); public Bullet bulletPrefab; void Awake () { if (singleton != null && singleton != this) { Destroy(gameObject); } else { singleton = this; } } void Start () { bulletPool = new ObjectPool (5, () => { Bullet bullet = Instantiate(bulletPrefab); bullet.Create(bulletPool); return bullet; }); bulletPool.Allocate(); } void OnDestroy () { bulletPool.Dispose(); singleton = null; } } // Gun.cs using UnityEngine; using System.Collections; public class Gun : MonoBehaviour { [HideInInspector] public Transform tm; private Vector3 bulletSpawnPoint; void Awake () { tm = gameObject.GetComponent (); bulletSpawnPoint = transform.FindChild("bulletSpawnPoint").transform.position; } void Update () { if (Input.GetMouseButtonDown(0)) { Bullet bullet = ObjectPoolManager.GetInstance().bulletPool.PopObject() as Bullet; bullet.Fire(bulletSpawnPoint); } } } // Bullet.cs using UnityEngine; using System.Collections; public class Bullet : PoolableObject { [HideInInspector] public Transform tm; [HideInInspector] public Rigidbody2D rb2D; private float force; public override void Create (ObjectPool pool) { base.Create (pool); } public override void Dispose () { base.Dispose (); } public override void _OnEnableContents () { base._OnEnableContents (); rb2D.Sleep(); } public override void _OnDisableContents () { base._OnDisableContents (); } void Awake () { tm = gameObject.GetComponent (); rb2D = gameObject.GetComponent (); force = 800.0f; } void OnEnable () { _OnEnableContents(); } void OnDisable () { _OnDisableContents(); } void Update () { if (tm.position.x > 10.0f) { Dispose(); } } public void Fire (Vector3 spawnPoint) { tm.position = spawnPoint; rb2D.AddForce(Vector3.right * force); } }
'NOTE > Unity' 카테고리의 다른 글
[Unity] Unity Script 정리 (0) | 2016.10.06 |
---|---|
[Unity] 로컬 데이터 베이스 저장 (0) | 2016.10.04 |
[Unity] Mobile & Input 2 (0) | 2016.09.30 |
[Unity] Mobile & Input (0) | 2016.09.29 |
[Unity] 짧은 개념 정리 (0) | 2016.09.29 |