Optimization for Instantiating/Destroying objects for mobile game

I currently have a spawning script that randomly generates obstacles and terrain objects on a big spinning ring, I recently starting using the unity profiler and noticed that the game is being bogged down and occasionally has a large spike in cpu usage. Basically everything is being spawned on a rotating ring then destroyed. I was wondering if anyone had any ideas on how to optimize this behavior or if someone had a different behavior in general that would be better to use. Here is the spawning script.

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

public class Generation : MonoBehaviour {

    // These are the spawn point arrays that are being used as placement for what's being spawned
    public Transform[] terrainPoints;
    public Transform[] obstaclePoints;
    public Transform[] middlePoints;
    // These are the actual list of prefabs that will be spawning
    public GameObject[] terrainSpawn;
    public GameObject[] obstacleSpawn;
    public GameObject[] middleSpawn;
    // These are the time intervals in which the spawnings will occur
    public float terrainTimer = 2;
    public float obstacleTimer = 2;
    public float middleTimer = 2;
    public float newTime = 2;
    // This is the bool that determines whether the game will be pause (this is accessed by another script, not set by this one)
    public bool isPause;
    // This is accessing the level ring of the level, this isn't set in the inspector this is set dynamically
    public GameObject theGround;

    public static Generation S;

    void Awake()
    {
        S = this;
        theGround = GameObject.Find("level ring");
    }
   
    // Update is called once per frame
    void Update () {
        // If isPause is set to false then we proceed to spawn the clones using the custom functions
        if(isPause == false)
        {
            TerrainSpawn();
            ObstacleSpawn();
            MiddleSpawn();
        }
    }
    // This is the function thats being called thats doing the spawning for terrain prefabs
    void TerrainSpawn()
    {
        // This is taking the duration of time and decreasing it by a set frame
        terrainTimer -= Time.deltaTime;
        // If this is below or equal to zero, it spawns a new clone
        if(terrainTimer <= 0)
        {
            // This randomly chooses an indexed prefab and transform and spawns something at those points
            GameObject terrainClone = Instantiate(terrainSpawn[Random.Range(0, terrainSpawn.Length)], terrainPoints[Random.Range(0, terrainPoints.Length)].transform.position, transform.rotation);
            terrainClone.transform.parent = theGround.transform;
            // This resets the duration of time for the next spawn
            terrainTimer = newTime;
        }
    }
    // This is the function called to spawn the obstacle clones
    void ObstacleSpawn()
    {
        obstacleTimer -= Time.deltaTime;
        if(obstacleTimer <= 0)
        {
            GameObject obstacleClone = Instantiate(obstacleSpawn[Random.Range(0, obstacleSpawn.Length)], obstaclePoints[Random.Range(0, obstaclePoints.Length)].transform.position, transform.rotation);
            obstacleClone.transform.parent = theGround.transform;
            obstacleTimer = newTime;
        }
    }
    // This is the function being called to spawn clones for the middle section prefabs
    void MiddleSpawn()
    {
        middleTimer -= Time.deltaTime;
        if(middleTimer <= 0)
        {
            GameObject middleClone = Instantiate(middleSpawn[Random.Range(0, middleSpawn.Length)], middlePoints[Random.Range(0, middlePoints.Length)].transform.position, transform.rotation);
            middleClone.transform.parent = theGround.transform;
            middleTimer = newTime;
        }
    }
}

Then I’m using a very basic destroy script.

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

public class DestroyClones : MonoBehaviour {

    // Use this for initialization
    void Start () {
        Destroy(gameObject, 7);
    }
   
    // Update is called once per frame
    void Update () {
       
    }
}

I also wanted to note that this is an endless runner game

Should read up on Object Pooling
EDIT: if you haven’th

I think i get the basic idea of object pooling, It’s basically reusing already spawned objects? However idk how to implement it with the current script i have just quite yet. Thanks for the tip!

yes it is indeed a fancy term for recycling. the general idea is to only instantiate what you don’t have yet, and use what you already have. You will need to track your generated assets.

When you need something, you run a check to see if you already have one in the scene.
If there is none, do an instantiate and put it into your list, array, or dictionary tracking generated objects in the scene.
If there is a copy, check if it’s already in use.
if it is not in use, enable that copy and reinstantiate it to its starting values
if it is in use, check if another copy can be used
if there is another copy, use that copy instead
if there are no usable copies, do the instantiate
DISCLAIMER(not true representation of code)

When you no-longer need something, you disable it instead of destroying it.

1 Like

hmmmmm, Thank you Laperen for the tips! I’ll see what i can come up with.