Search Unity

'ObjectPooler.GetPooledObject()': not all code paths return a value

Discussion in 'Scripting' started by Florentin16, Jan 20, 2020.

  1. Florentin16

    Florentin16

    Joined:
    Jan 15, 2020
    Posts:
    14
    what can i do?
    Code (CSharp):
    1. public GameObject pooledObject;
    2.  
    3. public int pooledAmount;
    4.  
    5. List<GameObject> pooledObjects;
    6.     // Start is called before the first frame update
    7.     void Start()
    8.     {
    9.        pooledObjects = new List<GameObject>();
    10.        for(int i = 0; i < pooledAmount; i++)
    11.        {
    12.               GameObject obj = (GameObject)Instantiate(pooledObject);
    13.            obj.SetActive (false);
    14.            pooledObjects.Add (obj);
    15.        }
    16.     }
    17.  
    18. public GameObject GetPooledObject()
    19. {
    20.    for(int i = 0; i < pooledObjects.Count; i++)
    21.    {
    22.           if(!pooledObjects[i].activeInHierarchy)
    23.        {
    24.               return pooledObject[i];
    25.        }
    26.    }
    27.  
    28. }
    29. }
    30.  
    And this:
    Cannot apply indexing with [] to an expression of type 'GameObject'
     
  2. ZO5KmUG6R

    ZO5KmUG6R

    Joined:
    Jul 15, 2010
    Posts:
    490
    a) You misspelled pooledObjects in your return statement on line 24
    b) If all objects are removed from the pool, your code passes the for statement and therefore has no return value
    Code (CSharp):
    1. public GameObject GetPooledObject()
    2. {
    3.    for(int i = 0; i < pooledObjects.Count; i++)
    4.    {
    5.           if(!pooledObjects[i].activeInHierarchy)
    6.        {
    7.               return pooledObjects[i];
    8.        }
    9.    }
    10.   return null; //can't find any objects to remove from pool
    11. }
     
  3. Karrzun

    Karrzun

    Joined:
    Oct 26, 2017
    Posts:
    129
    Your method needs to return a value (in this case a GameObject) even if there's no inactive one available from your list. One way you can achieve that is by adding a return null; into your method as a last line that only get's called when no object from your list is returned. I'd prefer a more robust way, though, along the lines of this:

    Code (CSharp):
    1. public bool GetPooledObject (out GameObject obj)
    2. {
    3.     obj = null;
    4.     for (int i=0; i<pooledObjects.Count; i++)
    5.     {
    6.         if (!pooledObjects[i].activeInHierarchy)
    7.         {
    8.             obj = pooledObjects[i];
    9.             return true;
    10.         }
    11.     }
    12.     return false;
    13. }

    Edit: Alternatively, you can add a new GameObject to your list if needed, of course. Then you don't need to change your return type.

    Code (CSharp):
    1. public GameObject GetPooledObject ()
    2. {
    3.     for (int i=0; i<pooledObjects.Count; i++)
    4.     {
    5.         if (!pooledObjects[i].activeInHierarchy)
    6.         {
    7.             return pooledObjects[i];
    8.         }
    9.     }
    10.     GameObject obj = (GameObject)Instantiate (pooledObject);
    11.     pooledObjects.Add (obj);
    12.     return obj;
    13. }
     
    Last edited: Jan 20, 2020
  4. Florentin16

    Florentin16

    Joined:
    Jan 15, 2020
    Posts:
    14
    Thanks guys for your help.