A Script is causing a spike on CPU usage

I was playing my game while the profiler was on and i noticed a frame drop and a spike on the Profiler, that seem to come from my respawner script.

The spike on the profiler

The info about the spike

Here’s the script:

using System.Collections;
using UnityEngine;

public class Respawner : MonoBehaviour {
    //=============//
    //=[VARIABLES]=//
    //=============//

    //Static variables
    public static Respawner current;

    //Cache variables
    WaitForSeconds timeToRespawn = new WaitForSeconds(5f);
    ChooseSpawn chosenSpawn = new ChooseSpawn();

    //==================//
    //=[INITIALIZATION]=//
    //==================//

    //Initialize the static variable
    void Awake()
    {
        current = this;
    }

    //===================//
    //=[RESPAWN METHODS]=//
    //===================//

    //Respawn an AI
    public IEnumerator RespawnAI(GameObject aiToRespawn,bool delaySpawn)
    {
        //Wait for 5 seconds
        if (delaySpawn)
            yield return timeToRespawn;

        //Choose a random spawn
        chosenSpawn.Initialize(aiToRespawn.tag);

        //Spawn AI
        aiToRespawn.transform.position = chosenSpawn.position;
        aiToRespawn.transform.rotation = chosenSpawn.rotation;
        aiToRespawn.SetActive(true);

        //Reset some stats
        aiToRespawn.GetComponent<MasterPlayerScript>().ResetStats();
        yield return null;
    }

    //Respawn a player
    public IEnumerator RespawnPlayer(GameObject player,bool delaySpawn)
    {
        //Wait for 5 seconds
        if (delaySpawn)
            yield return timeToRespawn;

        //Choose a random spawn
        CameraScript camera = CameraScript.current;
        chosenSpawn.Initialize(player.tag);

        //Spawn player and set camera
        player.transform.position = chosenSpawn.position;
        player.transform.rotation = chosenSpawn.rotation;
        player.SetActive(true);
        camera.target = player.transform;

        //Reset the stats of the player
        player.GetComponent<MasterPlayerScript>().ResetStats();
    }

    //===========//
    //=[CLASSES]=//
    //===========//

    //This class will output the spawns rotation and a random point around the spawn
    public class ChooseSpawn
    {
        public Vector3 position;
        public Quaternion rotation;

        //Initialize
        public void Initialize(string team)
        {
            //Chooses a ranodm spawn
            GameObject[] spawns = GameObject.FindGameObjectsWithTag(team + " Spawn");
            Transform chosenSpawn = spawns[Random.Range(0, spawns.Length)].transform;

            //Chooses a random point around the spawn
            Vector2 randomOnUnitCircle = Random.insideUnitCircle * 3 + new Vector2(chosenSpawn.position.x, chosenSpawn.position.z);

            //Sets values
            position = new Vector3(randomOnUnitCircle.x, chosenSpawn.position.y, randomOnUnitCircle.y);
            rotation = chosenSpawn.rotation;
        }
    }
    
}

Well, that spike is almost completely the GC.Collect (71%). Do you manually force a GC.Collect somewhere in your code?

I suggest you switch the profiler to “deep profile” and re-run the test. Also note that you seem to run your RespawnPlayer coroutine 18 times, are you sure that’s right? How many players do you respawn?

Anyways for each player you respawn you allocate about 200 bytes. That could be the spawn point array that each call of chosenSpawn.Initialize allocates.

You should cache your spawn points. Using “FindGameObjectsWithTag” is quite slow and, which is even worse, it allocates an array with all the spawn points each time you call the method.

So it would make sense to create a seperate spawn point manager script which does search for all spawn points at the map start and store them in a dictionary.

Keep in mind that coroutines are not methods but class instances. So each time you call StartCoroutine you will instantiate a coroutine. If you have a single respawn event for several players, it might be better to use a single coroutine which does the delay and then perform all the respawns at once.