Unity 对象池编写(上)
发表于2018-10-16
这篇文章给大家介绍下对象池吧,对象池说白了就是我们把经常实例化的东西经常实例然后又删除。这应该是常人的操作吧。而对象池的作用就是把后面哪一部分放到一个list里面,把它设置成setactive(false)。当我们再实例的时候然后从list中取。总体来说很简单。
首先我们假如要生成一个子弹,过会我们需要生产一个炮弹,对于这2中物体,我们应该生成2个池子然后用一个总池子去管理这2个小池子了,这些应该很好理解吧,当然这个池子在任何时候都可以被调用,所以这个池子应该是个单例。我建议单例最好去用单例组件那样去写。至于单例组件怎么写,我在下次消息出来机制中给大家详细的讲。这里有不讲了。
首先我们先看一下一个小池子的书写吧,我们定义这个类为objectpool。这个池子应该有最基本的3个方法吧首先初始化吧。这让我们知道这个池子里面是回收什么的,是可以生成什么的。接下来就是实例化一个游戏物体方法,回收一个游戏物体。同时也应该有一些辅助方法。例如将池子销毁掉方法,说实在的话不知道怎么和你们讲具体的代码,我还是贴代码。然后再代码中去讲解吧。
usingSystem; usingSystem.Collections.Generic; usingUnityEngine; usingObject=UnityEngine.Object; publicclassObjectPool { publiceventAction<GameObject>OnSpawnedEvent; publiceventAction<GameObject>onDespawnedEvent; publicGameObjectPrefab;//注释这个池子里面的原始东西。这个物体时子弹的话,那么这个池子就只生成和销毁子弹了。 publicintInstancesToPreallocate=5;//池子里面最多能有个数 publicintInstancesToAllocateIfEmpty=1;//池子最少的个数 publicintHardLimit=5;//最多限制个数 publicintInstancesToMaintainInPool=5; publicboolPersistBetweenScenes=false; privateStack<GameObject>_gameObjectPool; publicvoidInitialize()//初始化池子 { _gameObjectPool=newStack<GameObject>(InstancesToPreallocate); AllocateGameObjects(InstancesToPreallocate); } publicvoidClearStack()//这里池子用的数据结构是栈 你也可以用链表,队列都行。这个方法是清空栈 { if(_gameObjectPool.Count>InstancesToMaintainInPool) { for(inti=InstancesToMaintainInPool;i<_gameObjectPool.Count;i++) { Object.Destroy(_gameObjectPool.Pop()); } } } publicGameObjectSpawn()//实例化一个游戏物体 { vargo=Pop(); returngo; } publicvoidRecycleObj(GameObjectob)//回收一个游戏物体,将物体设置成不可见,然后放到栈中 { ob.transform.parent=Pools.Instance.gameObject.transform; ob.SetActive(false); _gameObjectPool.Push(ob); } privateGameObjectPop() { if(_gameObjectPool.Count>0) { return_gameObjectPool.Pop(); } AllocateGameObjects(InstancesToAllocateIfEmpty); returnPop(); } publicvoidClearPool(boolshouldDestroyAllManagedObjects)//qing { while(_gameObjectPool.Count>0) { vargo=_gameObjectPool.Pop(); if(shouldDestroyAllManagedObjects) Object.Destroy(go); } } privatevoidAllocateGameObjects(int count) { for(intn=0;n<count;n++) { GameObjectgo=Object.Instantiate(Prefab.gameObject)asGameObject; go.name=Prefab.name; if(go.transformasRectTransform) { go.transform.SetParent(Pools.Instance.Transform,false); go.SetActive(false); } else { go.transform.parent=Pools.Instance.Transform; go.SetActive(false); } _gameObjectPool.Push(go); } } }
当我们在看别人的代码结构的时候一些私有方法是可以不用看的,当你要具体了解某个类的作用的时候,这是才开始看。当然接口是最需要看。这只是一种类型物体的池子。我们下节看一个主管理池子的大池子。
来自:https://blog.csdn.net/u012565990/article/details/51702572