先聊聊对象池吧 ,说白了就是我们把经常实例化的东西经常实例 然后又删除。这应该是常人的操作吧。而对象池的作用就是把后面哪一部分放到一个list里面,把它设置成setactive(false)。当我们再实例的时候然后从list中取。总体来说很简单。


   首先我们假如要生成一个子弹,过会我们需要生产一个炮弹,对于这2中物体,我们应该生成2个池子 然后用一个总池子去管理这2个小池子了,这些应该很好理解吧,当然这个池子在任何时候都可以被调用,所以这个池子应该是个单例。我建议单例 最好去用单例组件那样去写。至于单例组件怎么写,我在下次 消息出来机制中给大家详细的讲。这里有不讲了。


  首先我们先看一下一个小池子的书写吧,我们定义这个类为objectpool。这个池子应该有最基本的3个方法吧 首先初始化吧。这让我们知道这个池子里面是回收什么的,是可以生成什么的。接下来就是实例化一个游戏物体方法,回收一个游戏物体。同时也应该有一些辅助方法。例如将池子销毁掉方法,说实在的话 不知道怎么和你们讲具体的代码 ,我还是贴代码。然后再代码中去讲解吧。

using System; 
 
 using System.Collections.Generic; 
 
 using UnityEngine; 
 
 using Object = UnityEngine.Object; 
 


 public class ObjectPool 
 
 { 
 
     public event Action<GameObject> OnSpawnedEvent; 
 
     public event Action<GameObject> onDespawnedEvent; 
 


     public GameObject Prefab;//注释这个池子里面的原始东西。这个物体时子弹的话 ,那么这个池子就只生成和销毁子弹了。 
 
     public int InstancesToPreallocate = 5;//池子里面最多能有个数 
 
     public int InstancesToAllocateIfEmpty = 1;//池子最少的个数 
 

     public int HardLimit = 5;//最多限制个数 
 
     public int InstancesToMaintainInPool = 5; 
 
     public bool PersistBetweenScenes = false; 
 


     private Stack<GameObject> _gameObjectPool; 
 




     public void Initialize()//初始化池子 
 
     { 
 
         _gameObjectPool = new Stack<GameObject>(InstancesToPreallocate); 
 
         AllocateGameObjects(InstancesToPreallocate); 
 
     } 
 


     public void ClearStack()//这里池子用的数据结构是栈  你也可以用链表,队列都行。这个方法是清空栈 
 
     { 
 
         if (_gameObjectPool.Count > InstancesToMaintainInPool) 
 
         { 
 
             for (int i = InstancesToMaintainInPool; i < _gameObjectPool.Count; i++) 
 
             { 
 
                 Object.Destroy(_gameObjectPool.Pop()); 
 
             } 
 
         } 
 
     } 
 


     public GameObject Spawn()//实例化一个游戏物体 
 
     { 
 


         var go = Pop(); 
 
         return go; 
 
     } 
 


     public void RecycleObj(GameObject ob)//回收一个游戏物体,将物体设置成不可见,然后放到栈中 
 
     { 
 
         ob.transform.parent = Pools.Instance.gameObject.transform; 
 
         ob.SetActive(false); 
 
         _gameObjectPool.Push(ob); 
 
     } 
 
     private GameObject Pop() 
 
     { 
 
         if (_gameObjectPool.Count > 0) 
 
         { 
 
             return _gameObjectPool.Pop(); 
 
         } 
 
         AllocateGameObjects(InstancesToAllocateIfEmpty); 
 
         return Pop(); 
 
     } 
 


     public void ClearPool(bool shouldDestroyAllManagedObjects)//qing 
 
     { 
 
         while (_gameObjectPool.Count > 0) 
 
         { 
 
             var go = _gameObjectPool.Pop(); 
 
             if (shouldDestroyAllManagedObjects) 
 
                 Object.Destroy(go); 
 
         } 
 
     } 
 
     private void AllocateGameObjects(int  count) 
 
     { 
 
         for (int n = 0; n < count; n++) 
 
         { 
 
             GameObject go = Object.Instantiate(Prefab.gameObject) as GameObject; 
 
             go.name = Prefab.name; 
 
             if (go.transform as RectTransform) 
 
             { 
 
                 go.transform.SetParent(Pools.Instance.Transform, false); 
 
                 go.SetActive(false); 
 
             } 
 
             else 
 
             { 
 
                 go.transform.parent = Pools.Instance.Transform; 
 
                 go.SetActive(false); 
 
             } 
 
             _gameObjectPool.Push(go); 
 
         } 
 
     } 
 
   
 

 }


当我们在看别人的代码结构的时候 一些私有方法是可以不用看的,当你要具体了解某个类的作用的时候,这是才开始看。当然接口是最需要看。这只是一种类型物体的池子。我们下节看一个主管理池子的大池子。