Search Unity

Unity C# Object pool script need Help!!!

Discussion in 'Scripting' started by LoveridgeDesigns, Jun 24, 2017.

  1. LoveridgeDesigns

    LoveridgeDesigns

    Joined:
    May 3, 2013
    Posts:
    69
    Hi guys,
    Basically this is my object pooling script



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class oBJECTpOOL : MonoBehaviour {
    6.  
    7.     public static oBJECTpOOL instance;
    8.  
    9.     /// <summary>
    10.     /// The object prefabs which the pool can handle.
    11.     /// </summary>
    12.     public GameObject[] objectPrefabs;
    13.  
    14.     /// <summary>
    15.     /// The pooled objects currently available.
    16.     /// </summary>
    17.     public List<GameObject>[] pooledObjects;
    18.  
    19.     /// <summary>
    20.     /// The amount of objects of each type to buffer.
    21.     /// </summary>
    22.     public int[] amountToBuffer;
    23.  
    24.     public int defaultBufferAmount = 3;
    25.  
    26.     /// <summary>
    27.     /// The container object that we will keep unused pooled objects so we dont clog up the editor with objects.
    28.     /// </summary>
    29.     protected GameObject containerObject;
    30.  
    31.     void Awake ()
    32.     {
    33.         instance = this;
    34.     }
    35.  
    36.     // Use this for initialization
    37.     void Start ()
    38.     {
    39.         containerObject = new GameObject("ObjectPool");
    40.  
    41.         //Loop through the object prefabs and make a new list for each one.
    42.         //We do this because the pool can only support prefabs set to it in the editor,
    43.         //so we can assume the lists of pooled objects are in the same order as object prefabs in the array
    44.         pooledObjects = new List<GameObject>[objectPrefabs.Length];
    45.  
    46.         int i = 0;
    47.         foreach ( GameObject objectPrefab in objectPrefabs )
    48.         {
    49.             pooledObjects[i] = new List<GameObject>();
    50.  
    51.             int bufferAmount;
    52.  
    53.             if(i < amountToBuffer.Length) bufferAmount = amountToBuffer[i];
    54.             else
    55.                 bufferAmount = defaultBufferAmount;
    56.  
    57.             for ( int n=0; n<bufferAmount; n++)
    58.             {
    59.                 GameObject newObj = Instantiate(objectPrefab) as GameObject;
    60.                 newObj.name = objectPrefab.name;
    61.                 PoolObject(newObj);
    62.             }
    63.  
    64.             i++;
    65.         }
    66.     }
    67.  
    68.     /// <summary>
    69.     /// 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
    70.     /// then null will be returned.
    71.     /// </summary>
    72.     /// <returns>
    73.     /// The object for type.
    74.     /// </returns>
    75.     /// <param name='objectType'>
    76.     /// Object type.
    77.     /// </param>
    78.     /// <param name='onlyPooled'>
    79.     /// If true, it will only return an object if there is one currently pooled.
    80.     /// </param>
    81.     public GameObject GetObjectForType ( string objectType , bool onlyPooled )
    82.     {
    83.         for(int i=0; i<objectPrefabs.Length; i++)
    84.         {
    85.             GameObject prefab = objectPrefabs[i];
    86.             if(prefab.name == objectType)
    87.             {
    88.  
    89.                 if(pooledObjects[i].Count > 0)
    90.                 {
    91.                     GameObject pooledObject = pooledObjects[i][0];
    92.                     pooledObjects[i].RemoveAt(0);
    93.                     pooledObject.transform.parent = null;
    94.                     pooledObject.SetActiveRecursively(true);
    95.  
    96.                     return pooledObject;
    97.  
    98.                 } else if(!onlyPooled) {
    99.                     return Instantiate(objectPrefabs[i]) as GameObject;
    100.                 }
    101.  
    102.                 break;
    103.  
    104.             }
    105.         }
    106.  
    107.         //If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
    108.         return null;
    109.     }
    110.  
    111.     /// <summary>
    112.     /// Pools the object specified.  Will not be pooled if there is no prefab of that type.
    113.     /// </summary>
    114.     /// <param name='obj'>
    115.     /// Object to be pooled.
    116.     /// </param>
    117.     public void PoolObject ( GameObject obj )
    118.     {
    119.         for ( int i=0; i<objectPrefabs.Length; i++)
    120.         {
    121.             if(objectPrefabs[i].name == obj.name)
    122.             {
    123.                 obj.SetActiveRecursively(false);
    124.                 obj.transform.parent = containerObject.transform;
    125.                 pooledObjects[i].Add(obj);
    126.                 return;
    127.             }
    128.         }
    129.     }
    130.  
    131. }
    and here is how i call the object pool.
    Code (CSharp):
    1. IEnumerator SpawnObject(int index, float seconds)
    2.     {
    3.         Debug.Log ("Waiting for " + seconds + " seconds");
    4.  
    5.  
    6.         yield return new WaitForSeconds(seconds);
    7.         spawnpos =oBJECTpOOL.instance.GetObjectForType ("ZombiePrefab", false);
    8.  
    9.  
    10.  
    11.  
    12.         //We've spawned, so now we could start another spawn
    13.             game.zombiesalive ++;
    14.         isSpawning = false;
    15.  
    16.     }


    The trouble im having is that i can't seem to figure out how to spawn these prefabs at predefined locations,(such as an empty gameobject which i assign in inspector)


    any advice would be greatly appreciated :)
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    If spawnpos (in your second script) is a game object, you just assign the location you want to its position? :)
     
    LoveridgeDesigns likes this.
  3. MilKID

    MilKID

    Joined:
    Jan 8, 2017
    Posts:
    16
    For predefined positions just make an serialized array of gameobjects and then in your spawning coroutine iterate through them. But do a check if they are occupied first - f.e. With Physics.OverlapSphere
     
    LoveridgeDesigns likes this.
  4. LoveridgeDesigns

    LoveridgeDesigns

    Joined:
    May 3, 2013
    Posts:
    69
    Code (CSharp):
    1. IEnumerator SpawnObject(int index, float seconds)
    2.     {
    3.         Debug.Log ("Waiting for " + seconds + " seconds");
    4.  
    5.  
    6.         yield return new WaitForSeconds(seconds);
    7.         spawnpos =oBJECTpOOL.instance.GetObjectForType ("ZombiePrefab", false);
    8.         spawnpos.transform.position = trans.transform.position;
    9.  
    10.  
    11.  
    12.  
    13.         //We've spawned, so now we could start another spawn
    14.             game.zombiesalive ++;
    15.         isSpawning = false;
    16.  
    17.     }

    im going to get some sleep now haha because i should have seen that solution haha ,
    thanks !!!
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Hey cool sleep well & no problem, you're welcome :)