Object pooling slower than instatiating new objects?

Okay so I’m making this Asteroids replica and I have this script that is supposed to keep all the asteroids that I could possibly use in one place away from the camera’s FOV and move them where I need them when I do (all the Asteroid objects have a script that calls the OnAsteroidCollision function when they get hit by a bullet). Before I made this script I had the asteroids just instatiate two other objects and destroy themselves and I moved to this because I thought it was good practice (I already use a similar script for pooling my bullets which works just fine).

The problem is that switching to this script gave me a HUGE performance hit. Starting the game takes forever now and there’s noticable lag when hitting the asteroids. The position in which the asteroids are supposed to be kept doesn’t seem to want to be where I set it either. Am I doing something wrong or should I just go back to instantiating new objects?

EDIT: The asteroids are set not to collide with each other.

using UnityEngine;

public class AsteroidInstatiator : MonoBehaviour {
    public int LargestAsteroidArraySize = 2;
    public GameObject Asteroid1;
    public GameObject Asteroid2;
    public GameObject Asteroid3;
    public GameObject Asteroid4;
    public Vector2 ArrayPosition;

    private GameObject[] Asteroid1Array;
    private GameObject[] Asteroid2Array;
    private GameObject[] Asteroid3Array;
    private GameObject[] Asteroid4Array;

    private int iterator1 = 0;
    private int iterator2 = 0;
    private int iterator3 = 0;
    private int iterator4 = 0;

    void Start()
    {
        Asteroid1Array = new GameObject[LargestAsteroidArraySize];
        Asteroid2Array = new GameObject[LargestAsteroidArraySize * 2];
        Asteroid3Array = new GameObject[LargestAsteroidArraySize * 4];
        Asteroid4Array = new GameObject[LargestAsteroidArraySize * 8];

        for (int i = 0; i < LargestAsteroidArraySize; i++)
        {
            Asteroid1Array[i] = GameObject.Instantiate(Asteroid1, ArrayPosition, Quaternion.identity);
        }

        for (int i = 0; i < LargestAsteroidArraySize * 2; i++)
        {
            Asteroid2Array[i] = GameObject.Instantiate(Asteroid2, ArrayPosition, Quaternion.identity);
        }

        for (int i = 0; i < LargestAsteroidArraySize * 4; i++)
        {
            Asteroid3Array[i] = GameObject.Instantiate(Asteroid3, ArrayPosition, Quaternion.identity);
        }

        for (int i = 0; i < LargestAsteroidArraySize * 8; i++)
        {
            Asteroid4Array[i] = GameObject.Instantiate(Asteroid4, ArrayPosition, Quaternion.identity);
        }
    }

    public void OnAsteroidDestroyal(GameObject CurrentAsteroidPrefab, GameObject CurrentObject)
    {
        if(CurrentAsteroidPrefab.name == "Asteroid_1")
        {
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator2 = Iterate(iterator2, "iterator2");

            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator2 = Iterate(iterator2, "iterator2");
        }

        else if (CurrentAsteroidPrefab.name == "Asteroid_2")
        {
            Asteroid3Array[iterator3].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid3Array[iterator3].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator3 = Iterate(iterator3, "iterator3");

            Asteroid2Array[iterator3].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid2Array[iterator3].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator3 = Iterate(iterator3, "iterator3");
        }

        else if (CurrentAsteroidPrefab.name == "Asteroid_3")
        {
            Asteroid4Array[iterator4].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid4Array[iterator4].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator4 = Iterate(iterator4, "iterator4");

            Asteroid4Array[iterator4].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid4Array[iterator4].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator4 = Iterate(iterator4, "iterator4");
        }

        CurrentObject.GetComponent<Rigidbody2D>().position = ArrayPosition;

    }

    public int Iterate(int iterator, string iteratorName)
    {
        if (iteratorName == "iterator1")
        {
            if (iterator == LargestAsteroidArraySize) return 0;
            else return iterator + 1;
        }

        else if (iteratorName == "iterator2")
        {
            if (iterator == LargestAsteroidArraySize * 2) return 0;
            else return iterator + 1;
        }

        else if (iteratorName == "iterator3")
        {
            if (iterator == LargestAsteroidArraySize * 4) return 0;
            else return iterator + 1;
        }

        else if (iteratorName == "iterator4")
        {
            if (iterator == LargestAsteroidArraySize * 8) return 0;
            else return iterator + 1;
        }

        else return 0;
    }
}

I can see a whole lot of things that are not really optimal in your code.
The biggest is your doing way too many GetComponent you need to be caching this. Think about just making your arrays RigidBody2D not gameobjects. You never actually seem to do anything with the game object you couldn’t do with a RigidBody2D.

You are doing way too many things with strings.

        if(CurrentAsteroidPrefab.name == "Asteroid_1")
        {
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator2 = Iterate(iterator2, "iterator2");
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().position = CurrentObject.GetComponent<Rigidbody2D>().position + new Vector2(5f, 5f);
            Asteroid2Array[iterator2].GetComponent<Rigidbody2D>().velocity = CurrentObject.GetComponent<Rigidbody2D>().velocity;
            iterator2 = Iterate(iterator2, "iterator2");
        }

You already know by the first name check that it is Asteroid_1 which is iterator 2 why not just do this in the same place.
Instead of calling Iterator again just do

if (iterator2 == LargestAsteroidArraySize * 2) iterator2 = 0;
else iterator2 ++;

You do not need to be passing a string to another function to then find the right index to increment.
If you really want to do this at least put your variables (LargestAsteroidArraySize and Iterator) into an array and then just pass the index to the function.

Another thing is I don’t see you turning them off? If you are not disabling them then im pretty sure they will keep moving when you move them out of range. You should probably be disabling them when they are destroyed and then enabling them when they get taken back out of the pool. Otherwise they will be taking resources as well.

You have basically a round robin / circular buffer type of system. As long as you can never have too many objects out this could work. But its possible you need more than you have allocated and then a active one will be reused and suddenly jump from one place to another.

2 Likes