Search code examples
c#unity-game-enginetimerswitch-statement

Delay Switch Scene C# Unity


I am creating an AR application that detects QR codes as the Target Images. I am detecting 4 QR codes and once a QR code is detected, a new scene needs to load. I am using a switch statement in my DefaultTrackableEventHandler script under the OnTrackingFound event.

The switch statement works. As soon as the target image is detected, it switches to the new scene. The issue is that it switches too fast. How can I delay this? I ahve tried the Invoke() method and the IEnumarator method without success.

Here is my code:

protected virtual void OnTrackingFound()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);

        // Enable rendering:
        foreach (var component in rendererComponents)
            component.enabled = true;

        // Enable colliders:
        foreach (var component in colliderComponents)
            component.enabled = true;

        // Enable canvas':
        foreach (var component in canvasComponents)
            component.enabled = true;


// This is where it detects the image target and loads new scene.
        switch (mTrackableBehaviour.TrackableName)
        {
          case "HLQRj":
                Invoke("PrintGRV", 5);
                SceneManager.LoadScene("PrintGRV");
                break;
           case "FSQRj":
                Invoke("PrintGRV", 5);
                SceneManager.LoadScene("PrintGRV");
                break;
           case "BPQRj":
                Invoke("PrintGRV", 5);
                SceneManager.LoadScene("PrintGRV");
                break;
           case "SPQRj":
                Invoke("PrintGRV", 5);
                SceneManager.LoadScene("PrintGRV");
                break;

        }

    }

Solution

  • It depends how long and for what you need to wait ... if you want to wait e.g. for a fixed time delay you can simply use a Coroutine e.g. using WaitForSeconds

    private IEnumerator SwitchScene()
    {
        // waits for 2 seconds
        yield return new WaitForSeconds(2);
    
        SceneManager.LoadScene("PrintGRV");
    }
    

    and run it like

    switch (mTrackableBehaviour.TrackableName)
    {
        case "HLQRj":
            Invoke("PrintGRV", 5);
            StartCoroutine(SwitchScene());
            break;
        //...
    }
    

    If you want to wait until a certain other async method is done you could also e.g. wait for a bool flag to become true as Draco18s mentioned correctly you can simply use WaitUntil

    private bool xyIsDone = false;
    
    private IEnumerator SwitchScene()
    {
        // wait until xyIsDone becomes true
        WaitUntil(xyIsDone);
    
        SceneManager.LoadScene("PrintGRV");
    }