Delay before scene.load

I know there are a few post about doing this, however there doesn’t seem to be one that works for what I need it for, if anyone could help please do and if there is a post that will work for this then please feel free to remove this post

    void Update() {
        if (dug_up) {
            spriteRenderer.enabled = true;
            if (Utils.f_chance (0.5f)) {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
//this is where I need a delay, so that the animation plays and then the next scene is loaded.
                SceneManager.LoadScene (1);

            }
        }
    }

There are a couple of ways to do this. A coroutine - a special function that does some stuff, then waits, then does more stuff - is probably the most straightforward:

if (Utils.f_chance(0.5f) ) {
StartCoroutine(SpawnThenLoad() );
}
}
}

// coroutines are always type IEnumerator
IEnumerator SpawnThenLoad() {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
// option 1: time
yield return new WaitForSeconds(5f);
// option 2: "wait one frame". Not good for this instance, but keep it in mind for the future
// yield return null;
SceneManager.LoadScene(1);
}

As StarManta said, you can use coroutines or you can load Scene but tell it not to switch untill you say to.
like this

    AsyncOperation levelLoading;
    void Update()
    {
        if (dug_up)
        {
            spriteRenderer.enabled = true;
            if (Utils.f_chance(0.5f))
            {
                Instantiate(items.light_bits, new Vector3(transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
                //this is where I need a delay, so that the animation plays and then the next scene is loaded.
                levelLoading = SceneManager.LoadSceneAsync(1);
                levelLoading.allowSceneActivation = false;

            }
        }
    }

    public void NowYouCanSwitchScene()
    {
        levelLoading.allowSceneActivation = true;
    }

And after your animation is done you should call this NowYouCanSwitchScene() method and scene will be changed

OxayMint I added your code into mine with no errors however when the animation happens the next scene doesn’t load, am I missing something?

Sorry to ask

Nick.

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

public class Treasure : MonoBehaviour {

    public bool dug_up = false;
    //public float delayTime =5; //this is just here as I was testing something.
    // References.
    SpriteRenderer spriteRenderer;
    ItemController items;

    void Awake() {
        spriteRenderer = GetComponent<SpriteRenderer>();
        items = GameObject.Find("ItemController").GetComponent<ItemController>();
    }

   /* void Update() {
        if (dug_up) {
            spriteRenderer.enabled = true;
            if (Utils.f_chance (0.5f)) {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);

                SceneManager.LoadScene (1);

            }
        }
    }*/

    AsyncOperation levelLoading;
    void Update()
    {
        if (dug_up)
        {
            spriteRenderer.enabled = true;
            if (Utils.f_chance(0.5f))
            {
                Instantiate(items.light_bits, new Vector3(transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
                //this is where I need a delay, so that the animation plays and then the next scene is loaded.
                levelLoading = SceneManager.LoadSceneAsync(1);
                levelLoading.allowSceneActivation = false;

            }
        }
    }

    public void NowYouCanSwitchScene()
    {
        levelLoading.allowSceneActivation = true;
        Debug.Log ("levelLoading"); // this isnt being called when the above happens.
    }

}

Hope this helps a little more with understanding whats happening.

Okay so here is a full update on the matter.

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

public class Treasure : MonoBehaviour {

    public bool dug_up = false;
    public float delayTime =5;
    // References.
    SpriteRenderer spriteRenderer;
    ItemController items;

    void Awake() {
        spriteRenderer = GetComponent<SpriteRenderer>();
        items = GameObject.Find("ItemController").GetComponent<ItemController>();
    }

   /* void Update() {
        if (dug_up) {
            spriteRenderer.enabled = true;
            if (Utils.f_chance (0.5f)) {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);

                SceneManager.LoadScene (1);

            }
        }
    }*/

    AsyncOperation levelLoading;
    void Update()
    {
        if (dug_up)
        {
            spriteRenderer.enabled = true;
            if (Utils.f_chance(0.5f))
            {
                Instantiate(items.light_bits, new Vector3(transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
                //this is where I need a delay, so that the animation plays and then the next scene is loaded.
                levelLoading = SceneManager.LoadSceneAsync(1);
                levelLoading.allowSceneActivation = false;
                Debug.Log ("Animation playing");// this is showing in unity 
                Invoke("NowYouCanSwitchScene", 5);

            }

        }
        //NowYouCanSwitchScene ();
    }

    public void NowYouCanSwitchScene()
    {
        levelLoading.allowSceneActivation = true;
        Debug.Log ("levelLoading");// this is now showing in unity but its not loading the level
    }

}

so both of my Debug.Logs are working and showing in Unity, but the levelLoading.allowSceneActivation = true; isn’t working right.
the attached image shows that the code is being called after the animation hence why the Debug.Log(“levelLoadign”); is showing up in Unity, but rather than loading the scene its… well I’m not too sure its trying to do it but its not able to for some reason. the image shows in the light red section that the main menu scene is being called but its not opening it… not sure why.

I’ve had to use an editor image as the game is fully PGC.

Two things going wrong.

First, it’s repeatedly loading the scene. This is because dug_up continues to be true, so every frame in Update it loads the new scene. You can either set dug_up to false, or created a new bool called “level_was_loaded” and ensure that that is false before you load the scene, and when the scene is loaded, set it to true.

^^^ Fix that one first, because if those scenes all get activated your editor will slow to a crawl and become a major PITA.

Second, it’s not activating any of the loaded scenes. I have a suspicion that what’s going on is that your levelLoading variable is getting constantly overwritten, so when the invoked function is called, it is not referring to the scene you loaded 5 seconds ago, but the one you just loaded. It’s possible that somehow this is causing the scene not to load at all? In any case, I give it a decent chance that if you fix the first problem, it might also fix the second, so fix that and let us know if it still won’t load.

Thank you StarManta, I’m going to take a look now

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

public class Treasure : MonoBehaviour {

    public bool dug_up = false;
    //public float delayTime =5;
    // References.
    SpriteRenderer spriteRenderer;
    ItemController items;

    void Awake() {
        spriteRenderer = GetComponent<SpriteRenderer>();
        items = GameObject.Find("ItemController").GetComponent<ItemController>();
    }

   /* void Update() {
        if (dug_up) {
            spriteRenderer.enabled = true;
            if (Utils.f_chance (0.5f)) {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);

                SceneManager.LoadScene (1);

            }
        }
    }*/

    AsyncOperation levelLoading;
    void Update()
    {
        if (dug_up) {
            spriteRenderer.enabled = true;
            if (Utils.f_chance (0.5f)) {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
                //this is where I need a delay, so that the animation plays and then the next scene is loaded.
                //levelLoading = SceneManager.LoadSceneAsync (1);
                //levelLoading.allowSceneActivation = false;
                Debug.Log ("Animation playing");
                WaitAndLoadScene ();//Calling the method
                Debug.Log ("load");// this is working as this is showing in Unity
            }

        }
    }
    IEnumerator WaitAndLoadScene()//Method for waiting and loading new scene
    {
    yield return new WaitForSeconds(5);
    SceneManager.LoadScene(1);
        Debug.Log ("Loading");//this is not happening in Unity
    }
       
}

Okay I’ve tried to create a delay in the WaitAndLoadScene method. no errors happen on the build. the Debug.Log (“load”); is showing in Unity which means its working down to there but its not doing anything with the WaitAndLoadScene (); part of the (Dug_up)

I think I need more help.

remember that WaitAndLoadScene() is a Coroutine because its return type is IEnumerator.

you need to call it inside StartCoroutine(WaitAndLoadScene()) for unity to run that method properly

AsyncOperation levelLoading;
    void Update()
    {
        if (dug_up) {
            spriteRenderer.enabled = true;
            if (Utils.f_chance (0.5f)) {
                Instantiate (items.light_bits, new Vector3 (transform.position.x, transform.position.y + 3, 0), Quaternion.identity);
                //this is where I need a delay, so that the animation plays and then the next scene is loaded.
                //levelLoading = SceneManager.LoadSceneAsync (1);
                //levelLoading.allowSceneActivation = false;
                Debug.Log ("Animation playing");
                StartCoroutine( WaitAndLoadScene ());
                Debug.Log ("load");
            }

        }
    }

Like this?

Yes.

thank you guys so much for your help.
the game is now fully finished and live on steams greenlight
http://steamcommunity.com/sharedfiles/filedetails/?id=850533987