UI button creates odd interactions after executing OnClick() mehtod

Hello. I’ve been going crazy over this all day. I need some help.

I have a very simple scene set up: 3 UI buttons parented to an empty GameObject (let’s call it the Pause Menu) which is parented to a Canvas. A script is attached as a component to the Canvas as well as the Resume and Quit buttons. Here it is:

using UnityEngine;
using System.Collections;

public class MainScript : MonoBehaviour
{

    public bool isPaused = false;
    public GameObject pauseMenu;

    // Use this for initialization
    void Start ()
    {

    }
 
    // Update is called once per frame
    void Update ()
    {
        if (Input.GetButtonDown("Cancel"))
        {
            Debug.Log("Paused / Unpaused");
            TogglePause();
        }
    }
 
    public void TogglePause()
    {
        if (!isPaused)
            {
                isPaused = true;
                pauseMenu.SetActive(true);
                Time.timeScale = 0;
            }
        else if (isPaused)
            {
                isPaused = false;
                pauseMenu.SetActive(false);
                Time.timeScale = 1;
            }
    }
 
    public void OnQuit()
    {
        #if UNITY_STANDALONE
            Application.Quit();
        #endif
 
        #if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
        #endif
    }
}

You can toggle pause/unpause using the Escape key to show/hide the Pause Menu GameObject. One of the buttons is “Resume” and it does the exact same thing as unpausing with the Escape key once it’s already paused.

Toggling the Pause Menu works flawlessly if you use the Escape key but as soon as you press the Resume button (which for some reason, you have to click twice) you have to press Escape twice to bring up the Pause Menu again. And then you keep having to click the Resume button twice to unpause. Please help, it’s driving me crazy.

I am using Unity v5.3.5f1 Personal Edition. I also attached the project as a zip file if you need to look into the scene yourself.

Thank you very much for taking an interest in my issue. Looking forward to your replies.

2668149–188240–TESTproject.zip (908 KB)

If you have that 1 script attached to multiple different objects, they do not share variables. Setting “isPaused” to true in one does not set it true in another.

For example:

  • you press escape, now your canvas pauses the game
  • you click the button, now your button tries to pause the game even though it’s already paused
  • you press escape again, the canvas tries to unpause the game
  • you press the button again, it tries to unpause the game

To fix this, you can use the “static” keyword before a variable so it’s shared between all instances, or you can have the scripts communicate to tell each other when the game is paused/unpaused.

Thank you very much, it works fine now.

At first I attached the script only to the Canvas, which seemed like a good idea since it’s one object in the scene that I will never destroy or hide but then, the buttons themselves, which are children of the Canvas object, could not find their specific functions, they don’t show up in the OnClick() section, only when I attach the script to each button they become available to select. Is there any way to achieve that without having to attach it to every single interactive button? Like to look for the functions in the script attached to their parent object?

You can make a variable point to another script and access anything that’s public in that other script.

For example, if you made a “ButtonScript” component with a “public MainScript” variable in it, you can drag-and-drop the canvas with the main script into the button script in the inspector (once they’re both on objects). You can then access anything that is public in MainScript using the ButtonScript.

example:

public class MainScript : MonoBehaviour
{

    public bool isPaused;

    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            isPaused = !isPaused;
        }
    }
}
public class ButtonScript : MonoBehaviour
{

    public MainScript _mainScript;

    void Update()
    {
        if(Input.GetButtonDown("Cancel"))
        {
            _mainScript.isPaused = !_mainScript.isPaused;
        }
    }
}

That’s so convenient. Thanks again! : )