Error in the console when pausing

Hi!! I have been having problems with the pause menu, for the time being I have the following error https://youtu.be/Wd6Q3_gIZ3o I have even tried to put the pause menu active but deactivate it in the start of the SHOWHIDEUI script, btw I don’t have that script I have figure it out by guessing that when pressing ESC the pause menu is activated and when pressing again deactivated. It is like it doesn’t find the component, but it only happens ONCE the second time I press ESC it doesn’t happen.

At 480p, it’s really hard to read the error message and the code itself… For future questions, always include a screenshot (or preferably the text) of the error message, and paste the code of the relevant scripts into the post. This will help me help you!

It looks like it’s saying the error is on line 24, in OnEnable(), and looking at the PauseMenuUI, I see that you’re caching the value of the PlayerController, rather than getting the PlayerController in OnEnable and OnDisable.

In this case, you’re caching the PlayerController in Start(), but OnEnable actually fires for the first time before Start.

Here’s the (simplified and relevant) execution order of a MonoBehaviour script:

  • Awake() → Always called once, and once only when the object is created whether or not the script is enabled or the GameObject is active. Best place to cache references.
  • OnEnable() → Called every time the script is enabled (or the relevant GameObject is activated)
  • Start() → Called once and once only after the first OnEnable(). If a reference is needed in OnEnable(), waiting to cache it here will cause a null reference.
  • Update() → Called every frame if the GameObject is active and the script is enabled.
  • OnDisable() → Called every time the script is disabled.
  • OnDestroy() → Called once only when the script is destroyed or the GameObject it is attached to is destroyed.

Moving the caching of the PlayerController from Awake() to Start() should resolve this issue.

using System.Collections.Generic;
using UnityEngine;
using theprinceofnerg.UI;
using theprinceofnerg.Control;
using theprinceofnerg.Saving;
using theprinceofnerg.SceneManagement;
public class ShowHideUI : MonoBehaviour,ISaveable
{
    #region ############## VARIABLES
    public GameObject UIContainer;
    SavingWrapper savingWrapper;
    public bool controllerOn;
  #endregion

  #region ############## EVENTS

    void Start()
    {
        controllerOn = true;
        savingWrapper = GameObject.Find("Saving").GetComponent<SavingWrapper>();

        UIContainer = GameObject.Find("PauseMenuUI");
        UIContainer.SetActive(false);
    }


    void Update()
    {
        if (controllerOn == true) {
            gameObject.GetComponent<PlayerController>().enabled = true;
        }
        if (controllerOn == false) {
            gameObject.GetComponent<PlayerController>().enabled =false ;
        }
        Controls();
    }
    #endregion

    #region ############# METHODS
    public void Controls() {
        
        if (Input.GetButtonDown("Cancel")) {
            Pause();
        }
    }

    public void Pause() {
        UIContainer.SetActive(!UIContainer.activeSelf);
        controllerOn =! controllerOn;
    }
    public object CaptureState() {
        return controllerOn;

    }

    public void RestoreState(object state) {

        controllerOn = (bool)state;
    }
    /// <summary>
    /// Cerramos el juego
    /// </summary>
    public void QuitGame() {

        savingWrapper.Delete();
        Application.Quit();
    }

Hi Brian, thank you for your response, with this script I’ve solved the issue. Created a bool that when the pause menu is activated the bool gets true if so player controller is enabled if not then viceversa. What do you think? For the time being this is working.
Best regards, have a great day!

This will work, but it puts a lot of weight on the Update() method, and this is easily avoided…

Let’s see if we can streamline this a bit, and even eliminate the need for a state bool:



void Update()
{
    Controls();
}

public void Pause()
{
    UIContainer.SetActive(!UIContanier.activeSelf);
    GetComponent<PlayerController>().enabled=UIContainer.activeSelf;
}

I’m not sure why you’re saving the state in Capture and RestoreState, as when we enter the game or transition scenes, you would want to be in a playable state. If you’re sure you want this, then here’s how I would go:

public object CaptureState()
{
    return GetComponent<PlayerController>().enabled;
}

public void RestoreState(object state)
{
    GetComponent<PlayerController>().enabled = (bool) state;
}

A quick note here: You’re freezing the PlayerController when the Pause Menu comes up, but the rest of the game will continue chugging along… meaning that the enemies will attack and murderize your character while you’re paralyzed in the pause menu.

If you add this to your PauseMenuUI(), you shouldn’t need to disable the PlayerController at all:

void OnEnable()
{
    Time.timeScale=0;
}
void OnDisable()
{
    Time.timeScale=1;
}

Then your ShowHideUI just needs to turn the PauseMenuUI on and off, and that’s pretty much it:

public class ShowHideUI : MonoBehaviour
{
     public GameObject UIContainer;
     
     void Awake()
     {
           UIContainer = GameObject.Find("PauseMenuUI");
           UIContainer.SetActive(false);
      }

      void Update()
      {
            if(Input.GetButtonDown("Cancel"))
            {
                 UIContainer.SetActive(!UIContainer.activeSelf);
            }
       }
}

Dear Brian, Thank you for your help, I don’t have enemies in my game. My game is more or less like this project: several rooms, pickables, inventory, need to save data between scenes… but there’s no enemies, you need to attack in one case of my game but you won’t lose health in no moment of my game. The game is based on dialogues, using your method, when I pause the game I can talk to the NPCs, well the dialogues don’t show up because they’re run by a script with a typewrite effect but it is shown the dialoguebox,I don’t know really that’s going on currently because I think I tried your method before asking you and why I have to put a bool in the update…this is what happens when I put it without the bool and the way you put it… First of all I have put the Pause canvas as a child of the PLAYER and the show hide UI script is attached to the player https://youtu.be/tjcCYcX_-GU

using System.Collections.Generic;
using UnityEngine;
using theprinceofnerg.UI;
using theprinceofnerg.Control;
using theprinceofnerg.Saving;
using theprinceofnerg.SceneManagement;
public class ShowHideUI : MonoBehaviour,ISaveable
{
    #region ############## VARIABLES
    public GameObject UIContainer;
    SavingWrapper savingWrapper;
    public bool controllerOn;
    #endregion

    #region ############## EVENTS
    void Awake() {
        UIContainer = GameObject.Find("PauseMenuUI");
        UIContainer.SetActive(false);
    }
    void Start()
    {
        savingWrapper = GameObject.Find("Saving").GetComponent<SavingWrapper>();
    }


    void Update()
    {
        //if (controllerOn == true) {
        //    gameObject.GetComponent<PlayerController>().enabled = true;
        //}
        //if (controllerOn == false) {
        //    gameObject.GetComponent<PlayerController>().enabled =false ;
        //}
        Controls();
    }
    #endregion

    #region ############# METHODS
    public void Controls() {
        
        if (Input.GetButtonDown("Cancel")) {
            Pause();
        }
    }

    public void Pause() {
        UIContainer.SetActive(!UIContainer.activeSelf);
        GetComponent<PlayerController>().enabled = UIContainer.activeSelf;

    }
    public object CaptureState() {
        //return controllerOn;
        return GetComponent<PlayerController>().enabled;

    }

    public void RestoreState(object state) {

        //controllerOn = (bool)state;
        GetComponent<PlayerController>().enabled = (bool)state;

    }
    /// <summary>
    /// Cerramos el juego
    /// </summary>
    public void QuitGame() {

        savingWrapper.Delete();
        Application.Quit();
    }

    #endregion
}

Also when going from one scene to another the PlayerController is not working well, only detects one click, it is always disabled. I have put it like before so it works until we find a solution… The key I think is the bool, when I put in the Pause functión controllerOn = !controllerOn; it works, I click any NPC being in pause menu and no dialogue box shows up.

Sorry, I was working on a set of assumptions about your game that weren’t true… At this point, I’m not sure what the purpose of the pause button is in the first place. Since the pause button in most games is designed to stop everything, I assumed that was what was desired, hence the TimeScale. If stopping the time isn’t desired, remove the suggested code from PauseMenuUI().

Yes, it is true, there’s no harm no danger in my game so implementing Pause Menu is not key, but it is in this case because it is a class project and maybe my teacher gets picky and can get mad for not implementing a PauseMenu. But you’re totally right, I’m going to implement it just in case the teacher gets strict…

If that’s the case, I would just stick to what’s working.

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.

Privacy & Terms