Android development. How to have two meanings of the same key?

Hello,

I’m making an Android game where I want to open a pause menu when the back-key is pressed. Then if you hit it again when the menu is opened, the menu should close. I have this code in a single script:

using UnityEngine;
using System.Collections;

public class PauseMenuScript : MonoBehaviour {
	private int GROUP_INSET_HORI;
	private int GROUP_INSET_VERT;
	private int GROUP_SIZE_HORI;
	private int GROUP_SIZE_VERT;
	
	private int BUTTON_INSET_HORI;
	private int BUTTON_INSET_VERT;
	private int BUTTON_SIZE_HORI;
	private int BUTTON_SIZE_VERT;
	
	public bool paused;
	public Texture buttonTexture;
	
	public GUIStyle myStyle;
	
	private Rect buttonRectUnity;
	
	// Use this for initialization
	void Start () {
		GROUP_INSET_HORI = Screen.width/8;
		GROUP_INSET_VERT = Screen.height/8;
		GROUP_SIZE_HORI = GROUP_INSET_HORI*6;
		GROUP_SIZE_VERT = GROUP_INSET_VERT*6;

		
		BUTTON_INSET_HORI = Screen.width/10;
		BUTTON_INSET_VERT = Screen.height/10;
		BUTTON_SIZE_HORI = GROUP_SIZE_HORI-2*BUTTON_INSET_HORI;
		BUTTON_SIZE_VERT = (int)(BUTTON_INSET_VERT*1.7);
		
		buttonRectUnity = new Rect(BUTTON_INSET_HORI,BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT);

		paused = false;
		Time.timeScale = 1; 
	}
	
	// Update is called once per frame
	void Update () {
		
	}
	
	void OnGUI(){
		if(paused){
			
			GUI.BeginGroup(new Rect(Screen.width/8,Screen.height/8,(Screen.width/8)*6,(Screen.height/8)*6));
				if(GUI.Button (new Rect(BUTTON_INSET_HORI,BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT),"Continue Game", myStyle)){
					paused = false;
					Time.timeScale = 1;
					GameEventManager.TriggerGameUnpaused();
				}
			
				if(GUI.Button (new Rect(BUTTON_INSET_HORI,3*BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT),"Restart Game", myStyle)){
					paused = false;
					Time.timeScale = 1;	
					GameEventManager.TriggerGameStart();
				}
			
				if(GUI.Button (new Rect(BUTTON_INSET_HORI,5*BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT),"Quit Game", myStyle)){
					Application.Quit();
				}
				if(Input.GetKeyUp (KeyCode.Escape)){
					paused = false;
					Time.timeScale = 1;
					GameEventManager.TriggerGameUnpaused();
						
				}	
				
				
			GUI.EndGroup();
			
		}
		else{
		    if(Input.GetKeyUp (KeyCode.Escape)){
			SetPaused ();
				
		    }
		}

	}
	
	public void SetPaused(){
		paused = false;
		StartCoroutine(PauseFunction(2));
		
		paused = true;
		Time.timeScale = 0;
		
		GameEventManager.TriggerGamePaused();
	}
	
	public IEnumerator PauseFunction(float pa){
		yield return new WaitForSeconds(pa);
		
	}
}

My problem is that the escape key triggers both if-statements, thereby opening the menu and imidiately closing it again. How can I make sure that one press on the back-button on the phone(or when testing on the computer on press on the escape-key) only counts once? Since I’m using OnKeyUp it should only be read once I think… I tried solving the problem by making a delay using WaitForSeconds, thereby possibly clearing the input-stream, but this did not work. It did not even pause the script…

I would be very grateful to anyone that can help me with this!

Thank you

[Edit]Made a correction to the code
[Edit]I now tried to have just on GetKeyUp statement in my code and then check if the game is paused or not but that does not work either. I have added the new OnGUI-function under this:

void OnGUI(){
		if(paused){
			GUI.BeginGroup(new Rect(Screen.width/8,Screen.height/8,(Screen.width/8)*6,(Screen.height/8)*6));
				if(GUI.Button (new Rect(BUTTON_INSET_HORI,BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT),"Continue Game", myStyle)){
					paused = false;
					Time.timeScale = 1;
					GameEventManager.TriggerGameUnpaused();
				}
			
				if(GUI.Button (new Rect(BUTTON_INSET_HORI,3*BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT),"Restart Game", myStyle)){
					paused = false;
					Time.timeScale = 1;	
					GameEventManager.TriggerGameStart();
				}
			
				if(GUI.Button (new Rect(BUTTON_INSET_HORI,5*BUTTON_INSET_VERT,BUTTON_SIZE_HORI,BUTTON_SIZE_VERT),"Quit Game", myStyle)){
					Application.Quit();
				}
 					
 		}
		if(Input.GetKeyUp (KeyCode.Escape)){
				
			if(paused){
				paused = !paused;
				Time.timeScale = 1;
				GameEventManager.TriggerGameUnpaused();
			}
			else{
				SetPaused ();
			}
		}
	}

The SetPaused-function is still the same.

You could simply set paused to inverted paused:

if(Input.GetKeyUp (KeyCode.Escape)){ paused = !paused; }

If paused is true, it will set it to false. If paused is false, it will set it to true.

How about changing:

if(Input.GetKeyUp (KeyCode.Escape)){
SetPaused ();
}

to:

else if(Input.GetKeyUp (KeyCode.Escape)){
  SetPaused ();
}

?

First of all, CoRoutines are run in parallel with the program. This means that it’ll be waiting for 2 seconds ONLY in the coroutine, but nowhere else in the program. To do what you’re trying to do there, you’ll need to change SetPause to a CoRoutine, then change your CoRoutine call to the WaitForSeconds statement.

Anyway, OnGUI runs at least twice per frame, so your button statement is firing twice. You shouldn’t put anything except GUI code into OnGUI, and move your input code into Update().

Basically, delete all of your input code from OnGUI(), and put this into Update():

if(Input.GetKeyUp(KeyCode.Escape)){
    paused = !paused;
    if(paused){
        GameEventManager.TriggerGamePaused();
    }
    else{
        GameEventManager.TriggerGameUnPaused();
    }
}

This will toggle pause whenever you hit escape, and your buttons will still appear.