Background
In the study of inventory Pro plug-in, found that the foreigner realized a generic object pool, feel the design of small and practical, dare not to stash, hereby shared.
I have seen a lot of Bo friends in the summary of the object pool sharing, but the world is so big, so complex what kind of object pool is good, we found that the Universal object pool may not adapt to all environments, such as UI-based local (from a scene, to a dialog) object pool, the scope of the different, The required pool of objects has different requirements. This article is about a preset (PREFAB)-based local UI object pool.
Implementation of common Information prompt window http://www.manew.com/thread-94647-1-1.html
Statement: This article started in the Bull, the second blog park, I original.
Original link 1http://www.manew.com/thread-94650-1-1.html, original link 2
Demonstrate
The information prompt in the lower left corner of the Noticeui window is more informative, with scrollbars and beyond auto-hide, which is achieved through object pooling technology to improve performance and efficiency
The following code is a related code that sets the object pool in Noticeui
Analysis
The usual first class diagram, but in fact there is no good analysis, is the object pool standard interface, take get and recycle here is destroy. There are two classes, one is generic, one is non-generic, and as for why struct is not a class, I do not delve into this piece.
Let's take a closer look at the class of the UI object pool, first of all the class
Declarations and constructors
1, class comments written very clearly, tell you that this object pool supports the object is gameobjects, restricts the type that must be Unity3d, the function of the class is only to improve the speed.
It is not perfect, it is recommended to use small-scale data. It's important to understand this, which is what I said in the background. The pool of objects used in each scenario is not the same and must not be mixed and misused.
2, the generic structure of the declaration, here we T limit the type is unityengine.component is the Unity3d component base class, so why the comment inside said only suitable for gameobjects, the rest is the new () keyword constraint, Make sure that the class can be new. Ipoolableobject is an interface-oriented implementation constraint (the framework layer is not the same), the actual is to enforce the code level of the object pool class management.
3, the constructor is using the default value StatSize64 is very intimate, the following three sentences initialization code, created a _poolparent gameobject, and hangs to the global component tree, I think this is particularly important, which makes it possible to see the dynamic creation and state of the pool object under Edit , especially to make the component tree particularly clear, like, the third sentence, that is, to save the generic object
Poolparent = new Gameobject ("_poolparent"). Transform;
Poolparent.setparent (InventoryManager.instance.collectionObjectsParent);
This.baseobject = Baseobject;
Initialization of a generic pool object
Pool Object Initialization Creation
The initialization of a generic pool object is actually a generic method overload called Gameobject.instantiate<t>, which is a deep clone. This explains why it is possible to complete a pool of objects for a preset (Prefab), then set its parent object, hook up to the component tree, and finally call Gameobject.setactivie (false) to make the UI object invisible, which is actually a switch.
Access and destruction of pool objects
Fetching of Pool objects
When a switch is created, the UI pool object can be used to determine if the object is already in use, and if active is false, the pool object is created by setting it to true, where the Createwhennoneleft parameter defaults to TRUE. To solve the problem of how the constructor preset pool objects are extended after they are used, it is quite simple here, when all the presets are used up and created again, thanks to the C # dynamic array list<t>, or the size of the array is dynamically resized like C + +.
Destruction of Pool objects
Object destruction is actually recycled, the simplest step in this object is SetActive (false), which is to turn the UI switch off, making the object invisible. In fact, it is important to call the Ipoolobject interface reset function implementation, to do some aftercare work, let's go through transform. SetParent () Resets the component tree. All objects are destroyed and recycled simply by looping through the destruction.
Core source
usingSystem;usingSystem.Collections.Generic;usingDevdog.inventorysystem;usingDevdog.InventorySystem.Models;usingUnityengine;namespacedevdog.inventorysystem{/// <summary> ///Only supports gameobjects and no unique types, just to speed some things up. ///It's not the ideal and I advice you to the use it on small collections. /// </summary> Public structInventorypool<t>whereT:unityengine.component, Ipoolableobject,New() { PrivateList<t>Itempool; PrivateTransform poolparent; PrivateT Baseobject; PublicInventorypool (T Baseobject,intStartsize = -) {poolparent=NewGameobject ("_poolparent"). Transform; Poolparent.setparent (InventoryManager.instance.collectionObjectsParent); This. Baseobject =Baseobject; Itempool=NewList<t>(startsize); for(inti =0; i < startsize; i++) {instantiate (); } } /// <summary> ///Create An object inside the pool/// </summary> /// <typeparam name= "T" ></typeparam> /// <param name= "obj" ></param> PublicT Instantiate () {varA = gameobject.instantiate<t>(Baseobject); A.transform.setparent (poolparent); A.gameobject.setactive (false);//Start DisabledItempool.add (a); returnA; } /// <summary> ///Get An object from the pool/// </summary> PublicT Get (BOOLCreatewhennoneleft =true) { foreach(varIteminchItempool) { if(Item.gameObject.activeSelf = =false) {item.gameObject.SetActive (true); returnitem; } } if(createwhennoneleft) {Debug.Log ("New object created, considering increasing the pool size if this is logged often"); returninstantiate (); } return NULL; } /// <summary> ///Mark An object as inactive it can recycled. /// </summary> /// <param name= "item" ></param> Public voidDestroy (T Item) {Item. Reset (); //resets the item Stateitem.transform.SetParent (poolparent); Item.gameObject.SetActive (false);//Up for reuse } Public voidDestroyall () {foreach(varIteminchItempool) Destroy (item); } } /// <summary> ///Inventorypool only good for gameobjects/// </summary> Public structInventorypool {PrivateList<gameobject>Itempool; PrivateTransform poolparent; PrivateGameobject Baseobject; PublicInventorypool (Gameobject Baseobject,intStartsize = -) {poolparent=NewGameobject ("_poolparent"). Transform; Poolparent.setparent (InventoryManager.instance.collectionObjectsParent); This. Baseobject =Baseobject; Itempool=NewList<gameobject>(startsize); for(inti =0; i < startsize; i++) {instantiate (); } } /// <summary> ///Create An object inside the pool/// </summary> /// <typeparam name= "T" ></typeparam> /// <param name= "obj" ></param> PublicGameobject Instantiate () {Gameobject a=NULL; if(Baseobject! =NULL) A= gameobject.instantiate<gameobject>(Baseobject); Elsea=NewGameobject (); A.transform.setparent (poolparent); A.gameobject.setactive (false);//Start DisabledItempool.add (a); returnA; } /// <summary> ///Get An object from the pool/// </summary> PublicGameobject Get (BOOLCreatewhennoneleft =true) { foreach(varIteminchItempool) { if(Item.gameObject.activeInHierarchy = =false) {item.gameObject.SetActive (true); returnitem; } } if(createwhennoneleft) {Debug.Log ("New object created, considering increasing the pool size if this is logged often"); returninstantiate (); } return NULL; } /// <summary> ///Mark An object as inactive it can recycled. /// </summary> /// <param name= "item" ></param> Public voidDestroy (Gameobject Item) {item.transform.SetParent (poolparent); Item.gameObject.SetActive (false);//Up for reuse } Public voidDestroyall () {foreach(varIteminchItempool) Destroy (item); } }}
View Code
Unity3d generic Object pool implementation based on presets (Prefab)