山寨小小军团开发笔记 之 GamePool

     很多时候我们对于物体(比如弓箭)大量的生成与销毁,这个时候可以把弓箭放在内存池中进行管理,加快体验。自己Copy了一个简易版的。

  

一、代码

GameObjectPoolManager.cs

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;



// A general pool object for reusable game objects.
//
// It supports spawning and unspawning game objects that are
// instantiated from a common prefab. Can be used preallocate
// objects to avoid calls to Instantiate during gameplay. Can
// also create objects on demand (which it does if no objects
// are available in the pool).
public class GameObjectPoolManager {

   public GameObject parent;



// The prefab that the game objects will be instantiated from. private GameObject prefab;
// The list of available game objects (initially empty by default). private Stack<GameObject> available; // The list of all game objects created thus far (used for efficiently // unspawning all of them at once, see UnspawnAll). private List<GameObject> all; // An optional function that will be called whenever a new object is instantiated. // The newly instantiated object is passed to it, which allows users of the pool // to do custom initialization. private Callback<GameObject> initializeFunction; private Callback<GameObject> destroyFunction; //// Indicates whether the pool's game objects should be activated/deactivated //// recursively (i.e. the game object and all its children) or non-recursively (just the //// game object). //private var setActiveRecursively : boolean; // Creates a pool. // The initialCapacity is used to initialize the .NET collections, and determines // how much space they pre-allocate behind the scenes. It does not pre-populate the // collection with game objects. For that, see the PrePopulate function. // If an initialCapacity that is <= to zero is provided, the pool uses the default // initial capacities of its internal .NET collections. public GameObjectPoolManager(GameObject prefab, Callback<GameObject> initializeFunction, Callback<GameObject> destroyFunction) { this.prefab = prefab; this.parent = new GameObject(prefab.name + "Pool"); this.available = new Stack<GameObject>(); this.all = new List<GameObject>(); this.initializeFunction = initializeFunction; this.destroyFunction = destroyFunction; } // Spawn a game object with the specified position/rotation. public GameObject Spawn(Vector3 position, Quaternion rotation) { GameObject result = null; if (available.Count == 0) { // Create an object and initialize it. result = GameObject.Instantiate(prefab, position, rotation) as GameObject; result.transform.parent = parent.transform; // Keep track of it. all.Add(result); } else { result = available.Pop() as GameObject; // Get the result's transform and reuse for efficiency. //Calling gameObject.transform is expensive. var resultTrans = result.transform; resultTrans.position = position; resultTrans.rotation = rotation; result.SetActive(true); } if (initializeFunction != null) initializeFunction(result); return result; } // Unspawn the provided game object. // The function is idempotent. Calling it more than once for the same game object is // safe, since it first checks to see if the provided object is already unspawned. // Returns true if the unspawn succeeded, false if the object was already unspawned. public bool Unspawn(GameObject obj) { if (!available.Contains(obj)) { // Make sure we don't insert it twice. available.Push(obj); obj.SetActive(false); if (destroyFunction != null) destroyFunction(obj); return true; // Object inserted back in stack. } return false; // Object already in stack. } // Pre-populates the pool with the provided number of game objects. void PrePopulate(int count){ GameObject[] array = new GameObject[count]; for(var i = 0; i < count; i++){ array[i] = Spawn(Vector3.zero, Quaternion.identity); //this.SetActive(array[i], false); } for(var j = 0; j < count; j++){ Unspawn(array[j]); } }
// Unspawns all the game objects created by the pool. void UnspawnAll() { foreach (var item in available) { Unspawn(item); } } // Returns the number of active objects. int GetActiveCount() { return all.Count - available.Count; } // Returns the number of available objects. int GetAvailableCount(){ return available.Count; } }

二、应用

还是用之前的BezierTest.cs的例子

    void Start()
    {
        arrowPool = new GameObjectPoolManager(arrowPrefab, null, null);

        //controlPoints = ControlPoints(transform, right);
    }
    #endregion



    void Test(bool fireRight)
    {
        Transform end = fireRight ? right : left;

        ///在中心点生成弓箭
        GameObject curArrow = arrowPool.Spawn(transform.position, Quaternion.Euler(Vector3.zero));

        ///计算LookTarget的点 与 贝塞尔曲线的第三个控制点
        Vector3[] points = Re_LookTarget_MiddlePerpendicularPoint(curArrow.transform, end);

        ///初始化发射
        ArrowControl arrowControl = curArrow.GetComponent<ArrowControl>();
        arrowControl.Init(
            points[0],
            points[1],
            end.position,
            3.0f,
            delegate()
            {
                arrowPool.Unspawn(curArrow);
            });
    }

  

原文地址:https://www.cnblogs.com/chongxin/p/4340125.html