Instantiate, Reset 和 Object Pool

Instantiate 是一个非常消耗性能的函数,所以尽量避免在运行时调用。这样我们就有了Reset()函数和 Object Pool 的运用。

Object Pool是一个GameObject的reference列表,他会在游戏开始时调用Instantiate函数创建出若干个Prefab Instance。然后将它们设置为无效,在游戏需要时从中找到有效的GameObject提供给游戏使用,当该GameObject需要destroy 时,他并不实际删除,只是简单的将它设置为无效回收到Object Pool中。

Reset 函数

MonoBehaviour提供Reset函数。该函数会在用户点击Inspector中的Reset按钮或者第一次添加该MonoBehaviour到GameObject的时候调用。通常我们利用他来设定初始默认值。

当我们将GameObject回收到Object Pool中的时候,我们一般希望他能够将该GameObject的数值或状态做一些重置,使得他们回到默认初始值以便下次使用。Reset函数的名字使得 他容易让人理解这个行为,所以我们就最大化地使用这个函数,通过 public 这个函数,使得Object Pool在回收的时候可以调用这个函数进行重置

Object Pool

以下是一份Object Pool的参考设置:

[System.Serializable]
public class EnemyPool {
 
    public int size;
    public GameObject prefab;
    private Enemy[] initEnemies;
 
    private int idx = 0;
    private Enemy[] enemies;
 
    // ------------------------------------------------------------------ 
    // Desc: 
    // ------------------------------------------------------------------ 
 
    public void Init ( exLayer _layer ) {
        initEnemies = new Enemy[size]; 
        if ( prefab != null ) {
            for ( int i = 0; i < size; ++i ) {
                GameObject obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject;
                initEnemies[i] = obj.GetComponent<Enemy>();
                obj.GetComponent<exLayer>().parent = _layer;
            }
        }
        Reset ();
    }
 
    // ------------------------------------------------------------------ 
    // Desc: 
    // ------------------------------------------------------------------ 
 
    public void Reset () {
        enemies = new Enemy[size];
        for ( int i = 0; i < size; ++i ) {
            enemies[i] = initEnemies[i];
            enemies[i].Reset();
            enemies[i].Show(false);
        }
        idx = size-1;
    }
 
    // ------------------------------------------------------------------ 
    // Desc: 
    // ------------------------------------------------------------------ 
 
    public Enemy Request ( Vector3 _pos, Quaternion _rot )  {
        if ( idx < 0 )
            Debug.LogError ("Error: the pool do not have enough free item.");
 
        Enemy result = enemies[idx];
        --idx; 
 
        result.transform.position = new Vector3 ( _pos.x, _pos.y, result.transform.position.z );
        result.transform.rotation = _rot;
        result.Show(true);
        return result;
    }
 
    // ------------------------------------------------------------------ 
    // Desc: 
    // ------------------------------------------------------------------ 
 
    public void Return ( Enemy _enemy ) {
        ++idx;
        _enemy.Reset();
        _enemy.Show(false);
        enemies[idx] = _enemy;
    }
}
posted @ 2012-03-21 11:33  渡蓝  阅读(525)  评论(0)    收藏  举报