Object pooling – Into the pool

As we have learned from our profiling session, one of the largest performance detriments on the mobile platforms is the constant creation and destruction of GameObjects. As you probably noticed earlier when we were testing out firing our weapons, there were noticeable pauses in the game every so often. Let's examine why this happens.

When an instance of the class GameObject is created in Unity on a mobile device, the device must allocate memory for this new instance of GameObject and potentially clear out memory that is used by some other object that may not be visible. This process, known as garbage collection, takes just enough time that it causes the pauses that you experience in the game. The reason this happens is due to the limited amount of memory available on the target devices and the time it takes to collect the old object. Java developers, particularly those that were brave enough to write games for the platform, are very familiar with the issues associated with garbage collection.

Typically, one will resolve some of the issues associated with garbage collection through the use of an object pool. An object pool allows one to allocate a number of objects up front and cycle through them such that new objects are never created. In the case of our weapon example we would allocate a number of objects in our game object pool that represent the max number of projectiles we want to be able to display at one time. As projectiles reach a certain distance from the player, we can remove them and free up a new object in the object pool for objects that are going to be visible next.

This particular implementation of an object pool was created by the Unity3D forum member and has an extension for particle systems as well as audio.

using UnityEngine;
using System;
using System.Collections;

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour
{
  
  public static ObjectPool instance;
   
  /// <summary>
  /// The object prefabs which the pool can handle.
  /// </summary>
  public GameObject[] objectPrefabs;
   
  /// <summary>
  /// The pooled objects currently available.
  /// </summary>
  public List<GameObject>[] pooledObjects;
  
  /// <summary>
  /// The amount of objects of each type to buffer.
  /// </summary>
  public int[] amountToBuffer;
  
  public int defaultBufferAmount = 3;
  
  /// <summary>
  /// The container object that we will keep unused pooled objects /// so we dont clog up the editor with objects.
  /// </summary>
  protected GameObject containerObject;
  
  void Awake ()
  {
    instance = this;
  }
  
  // Use this for initialization
  void Start ()
  {
    containerObject = new GameObject("ObjectPool");
  
    //Loop through the object prefabs and make a new list for //each one.
    //We do this because the pool can only support prefabs set to it //in the editor,
    //so we can assume the lists of pooled objects are in the same //order as object prefabs in the array
    pooledObjects = new List<GameObject>[objectPrefabs.Length];
    
    int i = 0;
    foreach ( GameObject objectPrefab in objectPrefabs )
    {
      pooledObjects[i] = new List<GameObject>();   
    
      int bufferAmount;
      
      if(i < amountToBuffer.Length) bufferAmount = amountToBuffer[i];
      else 
      bufferAmount = defaultBufferAmount;
      
      for ( int n=0; n<bufferAmount; n++)
      {
        GameObject newObj = Instantiate(objectPrefab) as GameObject;
        newObj.name = objectPrefab.name;
        PoolObject(newObj);
      }
    
      i++;
    }
  }

  /// <summary>
  /// Gets a new object for the name type provided.  If no object type /// exists or if onlypooled is true and there is no objects of that /// type in the pool
  /// then null will be returned.
  /// </summary>
  /// <returns>
  /// The object for type.
  /// </returns>
  /// <param name='objectType'>
  /// Object type.
  /// </param>
  /// <param name='onlyPooled'>
  /// If true, it will only return an object if there is one currently /// pooled.
  /// </param>
  public GameObject GetObjectForType ( string objectType , bool onlyPooled )
  {
    for(int i=0; i<objectPrefabs.Length; i++)
    {
      GameObject prefab = objectPrefabs[i];
      if(prefab.name == objectType)
      {
    
        if(pooledObjects[i].Count > 0)
        {
          GameObject pooledObject = pooledObjects[i][0];
          pooledObjects[i].RemoveAt(0);
          pooledObject.transform.parent = null;
          pooledObject.SetActiveRecursively(true);
          
          return pooledObject;
          
        } 
        else if(!onlyPooled) {
        return Instantiate(objectPrefabs[i]) as GameObject;
      }
    
      break;
    
    }
  }

  //If we have gotten here either there was no object of the specified //type or none were left in the pool with onlyPooled set to true
  return null; 
  }
   
  /// <summary>
  /// Pools the object specified.  Will not be pooled if there are no /// prefab of that type.
  /// </summary>
  /// <param name='obj'>
  /// Object to be pooled.
  /// </param>
  public void PoolObject ( GameObject obj )
  {
    for ( int i=0; i<objectPrefabs.Length; i++)
    {
      if(objectPrefabs[i].name == obj.name)
      {
        obj.SetActiveRecursively(false);
        obj.transform.parent = containerObject.transform;
        pooledObjects[i].Add(obj);
        return;
      }
    }
  }
   
}

The ObjectPool code is very straight-forward. It exposes several public variables so that you can configure it from the Unity IDE itself. The ObjectPool implemented here is designed to pool a variety of classes of objects at once. You don't need an implementation for each type of GameObject you want to pool. The ObjectPool stores each of the object types you want to pool in the ObjectPrefabs array.

Object pooling – Into the pool

By default the pool will create a maximum of three objects of each type. If you want to configure the amount of objects that an individual object can have, expand the Amount To Buffer element and set that size.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.102.249