Pause Menu Error, OnGui Breaks

Build System: Android
Scripts: Javascript

In my attempt at assigning the GUI.skin so I can control the fonts and styles of displaying “Paused”, I have broken my Pause System.

var gSkin : GUISkin;

and the above is set correctly in the Inspector.

The error I recieve is;
ArgumentException: You can only call GUI functions from inside OnGUI.

and the line it references is:

GUI.skin = gSkin;
Code Below

function OnGUI ()
{
	GUI.skin = gSkin;

//this is the line that Unity Halts on, whenever the Pause button is pressed. //And gives the error above, also you can’t unpause or do anything anymore.

	GUI.contentColor = Color.green;
	GUI.Label (Rect (25, 50, 200, 200), "Current Phase Is " + Phase1, "QAFont");
	
	if (LevelPause == true)
	{
		GUI.contentColor = Color.white;
		GUI.Label (Rect ((Screen.width/2)-50, 215, 200, 200), "Paused", "buttontext34shad");
		GUI.Label (Rect ((Screen.width/2)-55, 215, 200, 200), "Paused", "buttontext34");
	}
	if (LevelPause == false)
	{
		GUI.contentColor = Color.yellow;
		GUI.Label (Rect (375, 245, 200, 200), " ");
	}
}

function PauseLevel()
{
	LevelPause = true;
	savedTimeScale = Time.timeScale;
	Time.timeScale = 0;
	AudioListener.pause = true;
	var PlayerStop1 = GameObject.Find("Sheriff");
	var PlayerStop2 = (PlayerStop1.GetComponent(PlayerAttack) as PlayerAttack);
	PlayerStop2.enabled = false;
	OnGUI();
}

function UnPauseLevel()
{
	LevelPause = false;
	Time.timeScale = savedTimeScale;
	AudioListener.pause = false;
	var PlayerStop1 = GameObject.Find("Sheriff");
	var PlayerStop2 = (PlayerStop1.GetComponent(PlayerAttack) as PlayerAttack);
	PlayerStop2.enabled = true;
	OnGUI();
}

function IsGamePaused()
{
    return Time.timeScale==0;
}

If I comment out GUI.skin = gSkin; then everything works except I lose my fonts
and styles.

I am calling to pause off of the PlayerAttack script’s Update function, where all of the player inputs are defined.

It appears to me that the system is confused and thinking I am calling it outside of OnGUI, but I am not.

Below this line is where I am calling to Pausing the level, inside the Update() function of the player script.

function Update ()
{
	if (Input.GetButtonDown ("Fire1"))
	{
	
		var go = GameObject.Find("Sheriff");
		//Debug.Log("Player Fire Position is" + go.transform.position);//Checking Player Location, should be static
		SheriffFireLoc = new Vector3(go.transform.position.x,go.transform.position.y,transform.position.z); //exact player location in the world
		mouseHit = MousePoint();
		var lineRenderer : LineRenderer = GetComponent(LineRenderer);
		lineRenderer.enabled = true;
		lineRenderer.SetPosition (0, SheriffFireLoc);
		lineRenderer.SetPosition (1, MousePoint());

		if (RifleFire)
			audio.PlayOneShot(RifleFire);
	
	} 
	else 
	{
		var lineRenderer2 : LineRenderer = GetComponent(LineRenderer);
		lineRenderer2.enabled = false;
	}

	if (Input.GetButtonDown ("Menu"))
	{
			var LevelStatus1 = GameObject.FindWithTag("level");
			var LevelStatus2 = (LevelStatus1.GetComponent(LevelStatusCampaign) as LevelStatusCampaign);
			if (LevelStatus2.LevelPause == false)
			{	
				LevelStatus2.PauseLevel();
			}
			if (LevelStatus2.LevelPause == true)
			{
				LevelStatus2.UnPauseLevel();
			}
	}

		if (Input.GetButtonDown ("Back"))
	{
		//not currently assigned
	}

}

Try changing this section of your update function … if this doesn’t work … I’m out of suggestions :slight_smile:

     var LevelStatus:LevelStatusCampaign;

     function Start()
     {
       LevelStatus = GameObject.FindWithTag("level").GetComponent("LevelStatusCampaign");
     }

    function Update ()
    {    
        if (Input.GetButtonDown ("Menu"))
        {
            switch(LevelStatus.LevelPause)
            {
               case true:
                    LevelStatus.UnPauseLevel();
                    break;

               case false:
                    LevelStatus.PauseLevel();
                    break;
            }
        }    
    }

Remove the “OnGUI();” function calls from within your pause functions. OnGUI run automatically, all of the time.

Try this code rewrite:

var gSkin:GUISkin;
var LevelPause:boolean;
var savedTimeScale:float;
var PlayerStop1:GameObject;
var PlayerStop2:PlayerAttack;

function Start()
{
    LevelPause = false;
    PlayerStop1 = GameObject.Find("Sheriff");
    PlayerStop2 = PlayerStop1.GetComponent("PlayerAttack");
}
    
function OnGUI ()
{
    GUI.skin = gSkin;
    GUI.contentColor = Color.green;
    
    GUI.Label (Rect (25, 50, 200, 200), "Current Phase Is " + Phase1, "QAFont");

    if (LevelPause)
    {
        GUI.contentColor = Color.white;
        GUI.Label (Rect ((Screen.width/2)-50, 215, 200, 200), "Paused", "buttontext34shad");
        GUI.Label (Rect ((Screen.width/2)-55, 215, 200, 200), "Paused", "buttontext34");
    }
}

function PauseLevel()
{
    LevelPause = true;
    savedTimeScale = Time.timeScale;
    Time.timeScale = 0;
    AudioListener.pause = true;
    PlayerStop2.enabled = false;
}

function UnPauseLevel()
{
    LevelPause = false;
    Time.timeScale = savedTimeScale;
    AudioListener.pause = false;
    PlayerStop2.enabled = true;
}

function IsGamePaused()
{
    return Time.timeScale==0;
}

delete the previous versions of the PlayerStop2 and overwrite them with this:

var PlayerStop2:PlayerAttack;

function Start()
{
    PlayerStop2 = PlayerStop1.GetComponent("PlayerAttack");
}

That’s why … the Update() function is called 30 frames per second … ultimately, pausing (or unpausing) your game each time.

try taking your PauseLevel() and UnPauseLevel() function calls outside of the Update() function and put them on a button or key press.