読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

オブジェクトプール作ってみた

Unity

新型、作りました。
[Unity]新・オブジェクトプール



オブジェクトプールを作るのがちょっと面白そうだったので作ってみた。

Unity オブジェクトプールの作成 〜その1(ゲームは初心者にやさしく)
http://gamesonytablet.blogspot.jp/2012/09/unity.html

スクリーンショット 2012-09-12 0.03.23

デモ
https://dl.dropbox.com/u/56297224/UnitySumple2/Pool/mmd.html

■作ってみた

とりあえず適当に作ってみた。
このコードではこんな事をしてる。
1.プールから使えるオブジェクトを100個程作成
2.GetInstanceでアクティブじゃないオブジェクトを取得
 (全て使用済みならnullを返す)
3.使い終わったらActiveをfalseに

public class Pool : MonoBehaviour {	
[SerializeField]
private GameObject Prefub;
[SerializeField]
private int maxCount = 100;
private List objects = new List();
void Awake () {
for(int i=0; i< maxCount; i++)
{
GameObject obj = GameObject.Instantiate( Prefub ) as GameObject;
obj.gameObject.active = false;
obj.transform.parent = transform;
objects.Add( obj );
}
}
public GameObject GetInstance()
{
foreach( GameObject obj in objects)
{
if( obj.active == false )
{
Pool.Active(obj);
return obj;
}
}
return null;
}
public static void Active (GameObject obj)
{
foreach(Transform child in obj.GetComponentsInChildren(true))
{
child.gameObject.active = true;
}
}
public static void Deactive (GameObject obj)
{
foreach(Transform child in obj.GetComponentsInChildren(false))
{
child.gameObject.active = false;
}
}
}

使うときはこんな感じで使う。

GameObject obj = GetInstance();

オブジェクトを消すときはDestoryの代わりにDeactiveを使う。

■問題点

とりえあえず、GetInstanceで取得したオブジェクトは初期化してないので、取得時に初期化してやる必要がある
それにオブジェクト個数の限界を超えても増産しないので、上手くカバーしてやる必要がある。それとActive=falseでもメモリは消費するので、使ってなければ個数を減らす的な処理を作ってやると良さそう。そうすれば安心してオブジェクトの増産できる。
あとは現状だとDestroyみたいに一定時間後に自動で削除と言ったことが出来ない。それとActiveとかDeactiveのメソッドコンポーネントにもたせて、量産可能なインスタンスを区別したほうがスマートな気もする。そうすればStartCoroutine使えるから一定時間後Deactiveってのも出来るし。

うん、問題点だらけ