问题
I have my first runner game. Everything works fine. So, this question is about optimisation.
In my game, There are 15 platforms(road prefabs on which player runs). Randomly out 15 any 1 is instantiated and this keeps happening. When player passes a few platforms, The left behind platforms gets destroyed. I made a list to keep track of platforms and delete them last platform prefab ( list[0]). And new ones are instantiated ahead.
As the game approaches, It gets fast which means the operation of instantiating/destroying is happening more frequently now.
I read about object pooling. I understood the concept and I hold very strong opinion that I should use this in my game. I create an object pool. Works fine. Now my problem -
PROBLEM - How should I reuse object from my created pool? In my game, What I came up with is - The platforms that user has left behind should change position from back to forward( direction in which user is heading ). How can I achieve that ?
I followed these tutorials - https://www.youtube.com/playlist?list=PLLH3mUGkfFCXps_IYvtPcE9vcvqmGMpRK
回答1:
When player passes a few platforms, The left behind platforms gets destroyed. I made a list to keep track of platforms and delete them last platform prefab ( list[0]). And new ones are instantiated ahead.
There many ways to make Object pooling. One of them includes adding the Objects to a queue and removing them when they are in use. When you want to recycle/destroy them, add them back to the List instead.
How should I reuse object from my created pool?
It's really easy. Instead of doing this each time:
Instantiate(prefab, postion, Quaternion.identity);
Do it many times when the game begins in the Start function and store then in an Array/List:
List<GameObject> pool = new List<GameObject>();
void Start()
{
for (int i = 0; i < 50; i++)
{
GameObject tempObj = Instantiate(prefab, postion, Quaternion.identity) as GameObject;
pool.Add(tempObj);
}
}
When you need to instantiate Object during gameplay, just get one from the List/Array:
//Check if object is available in pool
if (pool.Count > 0)
{
//Object is. Return 1
GameObject objFromPool = pool[0];
//Enable the Object
objFromPool.SetActive(true);
}
else
{
//Object is NOT. Instantiate new one
GameObject objFromPool = Instantiate(prefab, postion, Quaternion.identity) as GameObject;
//Enable the Object
objFromPool.SetActive(true);
}
When you are done using the Object. Instead of doing Destroy(objFromPool);
, reset the position of that GameObject, maybe disable it also if you want then add it back to the List
:
//Reset Pos
objFromPool.transform.position = Vector3.zero;
//Disable?
objFromPool.SetActive(false);
//Return back to the array
pool.Add(objFromPool);
Finally, the best way of doing this is to instantiate all the objects into an array or list. Use an integer that you increment. The integer starts from 0 and increments until it reaches list/array.Length-1
. You can then use that integer to get an Object from the pool.
You can see example of this method implemented as ArrayObjectPooling
here and how to use it.
来源:https://stackoverflow.com/questions/44010299/object-pooling-implementation-reusing-in-unity-runner-game