많은 량의 객체들을 실시간으로 생성하고, 삭제하는 코드로 인해서 메모리가 빠르게 고갈되고,
쌓인 가비지로 인해 버벅거리는 현상이 발생한다면 메모리 풀 시스템을 활용하는게 좋습니다.
에셋스토어에도 그런 시스템을 판매하는걸로 알고 있지만, 직접 만들어 보았습니다.
많이 써보시고, 조금씩 수정하면서 사용하셔도 됩니다.
using UnityEngine;
using System.Collections;
//-----------------------------------------------------------------------------------------
// 메모리 풀 클래스
// 용도 : 특정 게임오브젝트를 실시간으로 생성과 삭제하지 않고,
// : 미리 생성해 둔 게임오브젝트를 재활용하는 클래스입니다.
//-----------------------------------------------------------------------------------------
//MonoBehaviour 상속 안받음. IEnumerable 상속시 foreach 사용 가능
//System.IDisposable 관리되지 않는 메모리(리소스)를 해제 함
public class MemoryPool : IEnumerable, System.IDisposable {
//-------------------------------------------------------------------------------------
// 아이템 클래스
//-------------------------------------------------------------------------------------
class Item
{
public bool active; //사용중인지 여부
public GameObject gameObject;
}
Item[] table;
//------------------------------------------------------------------------------------
// 열거자 기본 재정의
//------------------------------------------------------------------------------------
public IEnumerator GetEnumerator()
{
if (table == null)
yield break;
int count = table.Length;
for (int i = 0; i < count; i++)
{
Item item = table[i];
if (item.active)
yield return item.gameObject;
}
}
//-------------------------------------------------------------------------------------
// 메모리 풀 생성
// original : 미리 생성해 둘 원본소스
// count : 풀 최고 갯수
//-------------------------------------------------------------------------------------
public void Create(Object original, int count)
{
Dispose();
table = new Item[count];
for (int i = 0; i < count; i++)
{
Item item = new Item();
item.active = false;
item.gameObject = GameObject.Instantiate(original) as GameObject;
item.gameObject.SetActive(false);
table[i] = item;
}
}
//-------------------------------------------------------------------------------------
// 새 아이템 요청 - 쉬고 있는 객체를 반납한다.
//-------------------------------------------------------------------------------------
public GameObject NewItem()
{
if (table == null)
return null;
int count = table.Length;
for (int i = 0; i < count; i++)
{
Item item = table[i];
if (item.active == false)
{
item.active = true;
item.gameObject.SetActive(true);
return item.gameObject;
}
}
return null;
}
//--------------------------------------------------------------------------------------
// 아이템 사용종료 - 사용하던 객체를 쉬게한다.
// gameOBject : NewItem으로 얻었던 객체
//--------------------------------------------------------------------------------------
public void RemoveItem(GameObject gameObject)
{
if (table == null || gameObject == null)
return;
int count = table.Length;
for (int i = 0; i < count; i++)
{
Item item = table[i];
if (item.gameObject == gameObject)
{
item.active = false;
item.gameObject.SetActive(false);
break;
}
}
}
//--------------------------------------------------------------------------------------
// 모든 아이템 사용종료 - 모든 객체를 쉬게한다.
//--------------------------------------------------------------------------------------
public void ClearItem()
{
if (table == null)
return;
int count = table.Length;
for (int i = 0; i < count; i++)
{
Item item = table[i];
if (item != null && item.active)
{
item.active = false;
item.gameObject.SetActive(false);
}
}
}
//--------------------------------------------------------------------------------------
// 메모리 풀 삭제
//--------------------------------------------------------------------------------------
public void Dispose()
{
if (table == null)
return;
int count = table.Length;
for (int i = 0; i < count; i++)
{
Item item = table[i];
GameObject.Destroy(item.gameObject);
}
table = null;
}
}
using UnityEngine;
using System.Collections;
public class CsCube : MonoBehaviour {
public float speed = 2.0f;
public GameObject missilePrefab;
//missile time
float fireRate = 0.2f;
float startTime;
float shootTimeLeft;
MemoryPool pool = new MemoryPool();
GameObject[] missile;
// Use this for initialization
void Start () {
startTime = Time.time;
int poolCount = 10;
pool.Create(missilePrefab, poolCount);//메모리 풀 사용
missile = new GameObject[poolCount];
for (int i = 0; i < missile.Length; i++)
{
missile[i] = null;
}
}
void OnApplicationQuit()
{
pool.Dispose();//메모리 풀 삭제
}
// Update is called once per frame
void Update () {
float amtMove = speed * Time.deltaTime;
float key = Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * key * amtMove);
shootTimeLeft = Time.time - startTime;
//발사
if (Input.GetMouseButtonDown(0))
{
if (shootTimeLeft > fireRate)
{
for (int i = 0; i < missile.Length; i++)
{
if (missile[i] == null)
{
missile[i] = pool.NewItem();
missile[i].transform.position = transform.position;
break;
}
}
startTime = Time.time;
shootTimeLeft = 0.0f;
}
}
//미사일삭제
for (int i = 0; i < missile.Length; i++)
{
if (missile[i])
{
if (missile[i].transform.position.z > 20)
{
pool.RemoveItem(missile[i]);
// missile[i].GetComponent<CsMissile>().init();
missile[i] = null;
}
}
}
}
}
'잡다한것들전부 > 팁' 카테고리의 다른 글
| [함수] 유니티 함수 Vector3.Lerp에 대해서 알아보자. (0) | 2014.01.12 |
|---|---|
| 유니티 Vector3 를 상수 선언 하고 싶을때. (0) | 2014.01.09 |
| [펌][C# 강좌] 직접 만들어보는 메모리 풀 클래스 (0) | 2014.01.05 |
| 유니티 개발시 필요한 라이프 사이클 (0) | 2014.01.04 |
| 유니티 유/무료 강좌 (0) | 2014.01.04 |
| NGUI: Events (0) | 2014.01.04 |
MemoryPool.unitypackage

