1. Understand
The object pool is used to reduce memory overhead. Its principle is to store the objects that may be used in a place (pool) first, call them out when they need to be used, and put them back when they are not needed. Instead of creating it when you need it and destroying it when you don't need it.
Eg:
I have a plane to shoot bullets. The traditional method is to create bullets, hit the target or out of bounds, and destroy bullets. It is to create and destroy constantly. You should know that creation and destruction consume a lot of memory and time. If the bullet is stored in a place (pool), take it out when you need it and put it back when you don't need it.
If there are more than one aircraft, you can share a sub magazine.
Although this method has always maintained a maximum value of bullet storage space, it is very worth considering compared with the cost of continuous creation and destruction.
In actual development, the pool size can be appropriately enlarged or reduced as needed.
Object pool mode is not a unique design mode for game development. Its design idea is the same as that of database connection pool and thread pool in other development.
The core idea is not to delete it directly after use, but to put it back into the pool and take it out when necessary. The emergence of object pool mode mainly optimizes two points:
1. Prevent objects from being created and deleted frequently, resulting in memory jitter and frequent GC (garbage collection)
2. Object initialization costs are high
2. Operation
The following is a text introduction to the basic operation of the object pool
Borrowing: Generally speaking, it is to obtain objects from the pool. If you obtain objects for the first time, you should initialize the pool. If there is no desired object in the pool, create one
Return: Generally speaking, objects are to be deleted when they are used up, but after the object pool is applied, objects are returned to the pool on the premise that the number in the pool is not greater than the preset maximum number (to prevent too much memory explosion). If the number in the pool is greater than the preset maximum number, they are deleted directly
Preheating: preloading a certain number of objects. Personally, I think this is one of the more essential parts of the object pool. If preheating is not done, initialization is directly involved when creating objects for the first time. It's easy to understand that players would rather wait one second in the loading interface than get stuck for 0.1 seconds in the game, especially in competitive games, players will want to smash the computer (laugh). So I think if you don't do the object pool optimization of preheating, you only do half of it.
Shrink: it's almost like preheating. When returning, it says that if it is greater than the set quantity threshold, it will not be returned to the pool, but will be deleted directly. In fact, deletion may also bring time cost, so we can not delete it first, and then delete and shrink the memory pool every time we pass the loading interface in the middle of the game. If you are afraid that the memory will explode before loading the interface, you can set an additional threshold that must be deleted. Its function is the same as that written when returning it above. (I didn't do this function in my DEMO)
Reset: each newly taken object should be as "brand new" as the newly created one, and can not obviously have the last used state. Therefore, every time the object comes out of the pool, it should be reset where there may be aftereffects. In unity, the manual initialization of the object is written in OnEnable() of the object, including the force to empty the rigid body, etc. the difference between OnEnable() and Start() is that Start() only runs at the first frame when the object is enabled for the first time, and OnEnable runs every time the object is re enabled.
Object pool manager
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> ///Object pool manager /// </summary> public class PoolTest : MonoBehaviour { /* The core of object pool is collection Make a collection with a stack public Stack<GameObject> stack = new Stack<GameObject>(); You can also use list. It's relatively simple */ public List<GameObject> list = new List<GameObject>(); //Game prefab public GameObject GoPrefab; //Maximum number of objects in the object pool public int MaxCount=10; //Object into object pool public void Push(GameObject go) { //If the pool can still be filled, add it. If it is full, don't add it if (list.Count < MaxCount) { list.Add(go); } else { Destroy(go); } } //Take out the object from the object pool (the return value should be marked as GameObject) public GameObject Pop() { if (list.Count>0)//Judgment list is not empty { GameObject go = list[0];//If so, take out the first item list.RemoveAt(0);//Delete the first item in the list return go; } return Instantiate(GoPrefab);//If not, create a new preform directly } //Delete object pool public void Clear() { list.Clear(); } }
Test code
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Test : MonoBehaviour { //Used to manage preforms that are not stored in the object pool private List<GameObject> list = new List<GameObject>(); void Update() { //create object if (Input.GetKeyDown(KeyCode.A)) { GameObject go = GetComponent<PoolTest>().Pop(); list.Add(go); go.SetActive(true); } //delete object if (Input.GetKeyDown(KeyCode.S)) { if (list.Count>0)//Judge whether there are objects in the current scene { GetComponent<PoolTest>().Push(list[0]); list.RemoveAt(0); list[0].SetActive(false); } } } }
Hang two scripts on the same empty object
After running the project, we can clearly see that the preforms created are deleted by clicking the S key, not destroyed, but put into the object pool