Search code examples
unity-game-enginescene-manager

Why does successive loadings of scenes take a very long time?


I have a simple 2D top-down adventure game. There's a main level scene with houses. The player can enter the house and when doing so it deletes the main scene and loads the house scene. Respectively, when leaving the house, the player will load back the main scene.

The first few times of going back and forth between the house there is no problems. However, after loading the scene's back & forth multiple times, it takes 20 seconds or more to load between scenes.

How can this happen?

For each house, I have a door that has a public variable of the name of the Scene to be loaded.

This gets passed into a function that loads the scene

Code:

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

public class Transport : MonoBehaviour
{
    private GameObject hero;
    private Transform heroTransform;
    private BoxCollider2D heroCollider;
    private ButtonPress interactButton;
    private PlayerMovement heroScript;

    public string sceneName;
    public int doorId;
    public bool isEnter;
    public bool isLoading;

    public void Start()
    {
        isLoading = false;
        hero = GameObject.FindGameObjectWithTag("Player");
        heroScript = hero.GetComponent<PlayerMovement>();
        heroTransform = hero.transform;
        heroCollider = hero.GetComponent<BoxCollider2D>();

        interactButton = GameObject.FindGameObjectWithTag("InteractButton").GetComponent<ButtonPress>();
    }

    public void Update()
    {
        if (heroCollider.IsTouching(this.GetComponent<BoxCollider2D>())) {
            //Debug.Log("They are touching");
            if (interactButton.buttonPressed)
            {
                if(sceneName.Equals(""))
                {
                    // Do nothing...
                }
                else 
                {
                    // Only set return position if you are entering a door
                    if (isEnter)
                    {
                        heroScript.usedEnterDoor = true;
                        heroScript.setReturnPosition(heroTransform);
                    }
                    else
                    {
                        heroScript.usedEnterDoor = false;
                    }

                    if(isLoading == false)
                    {
                        //SceneManager.LoadScene(sceneName, LoadSceneMode.Single);
                        Debug.Log("Loading next scene...");
                        StartCoroutine(LoadYourAsyncScene(this.sceneName));
                        isLoading = true;
                    }
                }
            }
        }
    }


    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        isLoading = false;
    }


    IEnumerator LoadYourAsyncScene(string sceneName)
    {
        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);

        while(!asyncLoad.isDone)
        {
            yield return null;
        }
    }


}

The profiler showing the performance drop when scenes become slow to load is shown below:

Profiler: enter image description here

Profiler Deep Dive: enter image description here

Being a bit more careful on where I place the cursor... I see there is a huge use of "GameObject.Activate" 81,920 calls with 3 GB of garbage collection.

enter image description here


Solution

  • Figured it out. Thanks @TimChang for your help troubleshooting / on using the profiler tool. I had a button that was being set to active / inactive. It was being called thousands of times.