• 山寨小小军团开发笔记 之 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);
                });
        }
    

      

  • 相关阅读:
    Android内存管理篇
    Android内存管理篇
    Java:ServiceLoader未加载服务提供实现类
    Java:SPI机制
    利用向量积(叉积)计算三角形的面积和多边形的面积
    VMware虚拟机安装WinXP出现错误output error file to the following location A:GHOSTERR.TXT
    @media与css先后顺序产生的优先级问题
    css 始终显示滚动条,内容超出显示有滑块的滚动条,内容没有超出显示空的滚动条
    css 内容溢出显示垂直滚动条,内容不超出就不显示滚动条
    css 一行或多行文字溢出以...的形式隐藏
  • 原文地址:https://www.cnblogs.com/chongxin/p/4340125.html
Copyright © 2020-2023  润新知