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

public class BackToMainMenu : MonoBehaviour
{
    public PlayerCameraMouseLook cammouselook;

    // Update is called once per frame
    void Update ()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
            PlayerCameraMouseLook.mouseLookEnable = false;
            cammouselook.enabled = true;
        }
    }
}

Now when pressing the escape key it's loading the main menu scene. And in the main menu I have NEW GAME button but not RESUME.

Instead making a resume button I want that pressing the escape key again when the main menu scene is loaded it will return back to the game to the current position it is. Either if it's in a middle of a cutscene or just idle in the game.

So when pressing the escape key again it will back to the game and continue from the last point.

Another sub question : Should I use : LoadSceneMode.Additive ? Or when switching between the game play scene and the main menu it should remove the current active scene and then load the next one ?

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1, LoadSceneMode.Additive);

The main menu scene is at index 0 the game scene at index 1.

Main Menu

What I tried :

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

public class BackToMainMenu : MonoBehaviour
{
    // Variables
    private bool _isInMainMenu = false;
    public GameObject mainGame;
    public PlayerCameraMouseLook cammouselook;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (!_isInMainMenu)
            {
                SceneManager.LoadScene(0, LoadSceneMode.Additive);
                PlayerCameraMouseLook.mouseLookEnable = false;
                cammouselook.enabled = true;

                // -- Code to freeze the game
                mainGame.SetActive(false);
            }
            else
            {
                SceneManager.UnloadSceneAsync(0);
                // -- Code to unfreeze the game
                mainGame.SetActive(true);
            }

            _isInMainMenu = !_isInMainMenu;
        }
    }
}

And the Hierarchy :

The script is attached to the Back to main menu gameobject. And all the game objects are under Main Game.

Hierarchy

First time when pressing the escape key it's loading to the main menu and main menu scene to the hierarchy. Second time pressing on the escape key it's starting the game over like a new game and removing unloading the main menu.

In both cases the game scene is stay in the hierarchy.

1

1 Answers

0
votes

I will suggest you to add your main menu scene with the flag Additive as you mentioned.

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

public class BackToMainMenu : MonoBehaviour
{
    // Variables
    private bool _isInMainMenu = false;
    public PlayerCameraMouseLook cammouselook;

    // Update is called once per frame
    void Update ()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (!_isInMainMenu)
            {
                SceneManager.LoadScene(0, LoadSceneMode.Additive);
                PlayerCameraMouseLook.mouseLookEnable = false;
                cammouselook.enabled = true;

                // -- Code to freeze the game

            }
            else
            {
                SceneManager.UnloadSceneAsync(0);
                // -- Code to unfreeze the game
            }

            _isInMainMenu = !_isInMainMenu;
        }
    }
}

Take a look at the variable _isInMainMenu : it will track if you are in the main menu or not. Depends on the value, the Escape key will behave differently.

Note : I suggest you to type the current index of the scene in LoadScene / UnloadSceneAsync, unless you may want to change their index. In this scenario, type the scene name (Methods overload).

Now what I mean with // -- Code to freeze the game depends on your game :

  • You can have a unique GameObject that contains all the others GameObjects your scene has, and Enable / Disable it
myBigGameObject.SetActive(true/*or false*/);
  • Have a logic in MonoBehaviour to freeze the game while your in the main menu. For example you can use the bool _isInMainMenu in Update() to stop them from doing their job ;

For example in this MonoBehaviour I created as an example :

public class ExampleMonoBehaviour : MonoBehaviour
{
    private void Update ()
    {
        if (_isInMainMenu)
            return;
        print("I'm running !");
    }
}
  • Have a Collection (List as an example) that stores every top hierarchy GameObjects and enable/disable them all as needed to behave the same as above.

Depends on how your code is, there is many other options. I will highly suggest you to do the first or third option, unless you have a better approach.

The thing is, if you want to go back to the main menu, it shouldn't be very expansive (loading time, memory usage, ...) so you can disable GameObject from the main scene (third point) to restore them back quickly when you leave the main menu without reloading the entire scene. This would lead you to use serialization and deserialization.


Edited : Typo