0
\$\begingroup\$

the code below is the code I use to load my game scene ater the intro animation plays. The way it works is that it preloads the game scene because it is big enough it takes time to load and activates it after 15 seconds.

I want to use this code in a similar manner for my main menu, but instead of preloading and waiting for seconds I want it to preload and wait for UI button.

public class IntroToForest : MonoBehaviour
{
    public float WaitToLoad = 14.0f;

    void Start()
    {
        StartCoroutine(LoadScene(WaitToLoad));
    }

    IEnumerator LoadScene(float WaitToLoad)
    {
        yield return null;
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("Forest Map");
        asyncOperation.allowSceneActivation = false;

        while (!asyncOperation.isDone)
        {
            if (asyncOperation.progress >= 0.9f)
            {
                yield return new WaitForSeconds(WaitToLoad);
                asyncOperation.allowSceneActivation = true;
            }
            yield return null;
        }
    }
}

Side note: I incorporated DmGregory's answer into my menu controller script and got this:

public class MenuController : MonoBehaviour
{
    public string SceneName;

    AsyncOperation preload;

    void Start()
    {
        preload = SceneManager.LoadSceneAsync(SceneName);
        preload.allowSceneActivation = false;
    }
    public void Go_to_game()
    {
        if (preload.progress < 0.9f)
        {
            if (PlayerPrefs.HasKey("HasSeenIntro"))
            {
            preload.allowSceneActivation = true;
            }
            else
            {
                PlayerPrefs.SetInt("HasSeenIntro", 1);
                SceneManager.LoadScene("Intro");
            }
        }
    }
}

The problem is that the UI button will not work.

\$\endgroup\$
  • \$\begingroup\$ @DMGregory I changed the question so it should be easier to understand. \$\endgroup\$ – Ethan K-B Aug 9 '19 at 19:18
  • \$\begingroup\$ Can you clarify the actual problem part? Is it that you essentially want to also wait for a button press at the end? \$\endgroup\$ – MichaelHouse Aug 9 '19 at 21:38
  • \$\begingroup\$ @MichaelHouse Basically the script I posted will wait to a set amount of time to load the scene. I want it to rely on a ui button being pressed instead of a timer. \$\endgroup\$ – Ethan K-B Aug 9 '19 at 21:41
  • \$\begingroup\$ So, you wait until it's 90% loaded, then as long as it's still not loaded, wait 14 seconds each time you check. Instead, you want to go to 90% and then wait for a button press? Ah I see, you're using the example: docs.unity3d.com/ScriptReference/… \$\endgroup\$ – MichaelHouse Aug 9 '19 at 21:51
  • \$\begingroup\$ You did not implement the answer correctly. allowSceneActivation = true should not be gated by your progress check, otherwise you skip transitioning to the scene if it's not already loaded when the button is clicked. \$\endgroup\$ – DMGregory Aug 10 '19 at 23:28
2
\$\begingroup\$

Rather than running this as a coroutine, ticking every frame waiting to see if the button is pressed, I'd just store the AsyncOperation and let the button give it a kick when the player finally presses it.

public class ScenePreloader : MonoBehaviour {

    public string sceneName;

    AsyncOperation preload;

    void Start() {
        preload = SceneManager.LoadSceneAsync(sceneName);
        preload.allowSceneActivation = false;
    }

    // Call this from your UI button.
    public void BeginTransition() {
        preload.allowSceneActivation = true;

        if(preload.progress < 0.9f) {
            // Here, you might want to display a loading spinner,
            // so you have coverage if the user is very fast / load is slow.
        }            
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Is there a way to do this with 2 scenes? \$\endgroup\$ – Ethan K-B Aug 10 '19 at 19:34
  • 1
    \$\begingroup\$ That sounds like a different question than the one you've asked above. The tricky bit is there's no way to cancel an asynchronous scene load that I know of, so safely disposing of preloaded scene A when the player has decided to go to preloaded scene B instead could require some extra work. \$\endgroup\$ – DMGregory Aug 10 '19 at 19:40
1
\$\begingroup\$

Just use a boolean flag.

public class IntroToForest : MonoBehaviour
{
    public bool buttonPressed = false;

    void Start()
    {
        StartCoroutine(LoadScene("Forest Map"));
    }

    IEnumerator LoadScene(string scene)
    {
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(scene);
        asyncOperation.allowSceneActivation = false;

        while (!asyncOperation.isDone)
        {
            if (asyncOperation.progress >= 0.9f)
            {
                if(buttonPressed)
                    asyncOperation.allowSceneActivation = true;
            }
            yield return null;
        }
    }
}

Configure your button in the Inspector to set buttonPressed to true when pressed.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ MichaelHouse Nothing Happens when I press the button. \$\endgroup\$ – Ethan K-B Aug 10 '19 at 21:11
1
\$\begingroup\$

You can use WaitWhile to define a condition for the coroutine's yield. Something like this could work, with a button configured to update the value of buttonPressed accordingly.

public class IntroToForest : MonoBehaviour
{
    public bool buttonPressed;

    void Start()
    {
        StartCoroutine(LoadScene());
    }

    IEnumerator LoadScene()
    {
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("Forest Map");
        asyncOperation.allowSceneActivation = false;

        while(!asyncOperation.isDone)
        {
            yield return new WaitWhile(() => !buttonPressed);
            if (asyncOperation.progress >= 0.9f)
            {
                asyncOperation.allowSceneActivation = true;
            }
        }
    }
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.