I get the feeling that this is another simple “I’m overlooking something” deal, but when I’m trying to make a pause menu, I get no errors until I try to play. Then it throws up "InvalidProgramException: Invalid IL code in pauseMenu:BeginPage (object,object): IL_0010: sub
pauseMenu.PauseMenu () (at Assets/Scripts/pauseMenu.js:444)
pauseMenu.OnGUI () (at Assets/Scripts/pauseMenu.js:193)".
Here’s the lines it’s mentioning (bolded and underlinedin the pasted functions):
function PauseMenu()
{
__[B]BeginPage(200, 200);[/B]__
//If our button is pressed....
if(GUILayout.Button(IsBeginning() ? "Play":"Continue"))
{
//...we'll unpause the game.
UnPauseGame();
}
//If our options button is pressed...
if(GUILayout.Button("Options"))
{
//...we'll set our current page/navigate to the options page.
currentPage = Page.Options;
}
//If our credits button is pressed...
if(GUILayout.Button("Credits"))
{
//....we'll set our current page/navigate to the credits page.
currentPage = Page.Credits;
}
//If we're in the browser, not IsBeginning, and our restart button is pressed.....
if(IsBrowser() !IsBeginning GUILayout.Button("Restart"))
{
//...we'll open our url.
Application.OpenURL(url);
}
//Now we'll end the page.
EndPage();
}
And:
function OnGUI()
{
//If we have a skin...
if(skin != null)
{
//...we'll set it to GUI.skin.
GUI.skin = skin;
}
ShowStatNums();
ShowLegal();
//If our game is paused...
if(IsGamePaused())
{
//...We'll set our GUI color and...
GUI.color = statColor;
//...see what case should be run.
switch(currentPage)
{
case Page.Main:
__[B]PauseMenu();[/B]__
break;
case Page.Options:
ShowToolbar();
break;
case Page.Credits:
ShowCredits();
break;
}
}
}
I can paste the rest of the code if needed.
content of BeginPage would be usefull as thats what is failing.
Sorry, meant to include that.
function BeginPage(width, height)
{
GUILayout.BeginArea(Rect((Screen.width - width)/2, (Screen.height - height)/2, width, height));
}
I got to playing with it and trying to recreate your problem… Unfortunately I didn’t get the error.
Try hacking it down and testing it piece by piece.
function OnGUI () {
var s="this is a test";
BeginPage(200, 200);
GUILayout.Label(s);
if(GUILayout.Button("Options"))
{
//...we'll set our current page/navigate to the options page.
print("click");
}
EndPage();
}
function BeginPage(width, height)
{
GUILayout.BeginArea(Rect((Screen.width - width)/2, (Screen.height - height)/2, width, height));
}
function EndPage(){
GUILayout.EndArea();
}
I just noticed something else… Whenever I have the script attached, it seems to ignore the other scripts (so my enemies don’t get spawned and while I can move the character, it doesn’t play the walking or running animations)… If the pause script isn’t attached to anything, everything else works.
What’s even stranger is that if I build it, I can pause the game and the spawn/animation issues above are not present, it just doesn’t show the pause menu 
I’m going to go ahead and post the rest of the script (first time I’ve tried something like this, so I used the example on the Unify community wiki with a few changes)… Maybe there’s something in it somewhere else causing the issue?
(Unfortunately it puts the message over 4000 characters over the limit, so I have to double post.)
//Let's begin by setting up our skin.
var skin:GUISkin;
//Now we'll declare some private variables for the time and gldepth.
private var gldepth = -.5;
private var startTime = .1;
//Next we'll set up our material.
var mat:Material;
//And declare some more private variables. We'll seperate the booleans with a line break to make
//it easier to read.
private var tris = 0;
private var verts = 0;
private var savedTimeScale:float;
private var pauseFilter;
private var showfps:boolean;
private var showtris:boolean;
private var showvtx:boolean;
private var showfpsgraph:boolean;
//Now let's set our lowFPS and highFPS colours.
var lowFPSColor = Color.red;
var highFPSColor = Color.green;
//And set what values are high and low.
var lowFPS = 30;
var highFPS = 50;
//Let's go ahead and declare our "Start" game object.
var start:GameObject;
//And set our statColor. We don't want this to be the same as either of our FPS colours!
var statColor:Color = Color.yellow;
//Go ahead and set up a quick, sample credits string. This will be modified as the project nears completion.
var credits:String[] = [
"A class project.",
"Programming by",
"Sounds by .",
"Level Design by ."];
var crediticons:Texture[];
var url = "unity.html";
//Let's set up our pages via enum. We can add more or subtract from this if needed later, and if we do,
//we need to remember to edit this enum!
enum Page
{
None, Main, Options, Credits
}
//Now we'll set up a variable so that our game will know what page we're on.
private var currentPage:Page;
//Next let's go ahead and give our frames per second an array and a flaot.
private var fpsarray:int[];
private var fps:float;
//Now we get into our first function. This function is only called when the game is started.
function Start()
{
fpsarray = new int[Screen.width];
Time.timeScale = 1.0;
//Let's set a pause filter by grabbing an effect from our main camera.
//pauseFilter = Camera.main.GetComponent(SepiaToneEffect);
//The line above will set a Sepia tone effect if we have one on our main camera. Unless we
//have Unity Pro, the line is useless, as the free version does not support it.
PauseGame();
}
function OnPostRender()
{
//If fpsgraph is showing and our material isn't null...
if(showfpsgraph mat != null)
{
//..we'll push and load our Matrix.
GL.PushMatrix();
GL.LoadPixelMatrix();
//Now we'll set up our loop.
for(var i = 0; i < mat.passCount; ++i)
{
mat.SetPass(i);
GL.Begin(GL.LINES);
//And a loop within our main loop.
for(var x = 0; x < fpsarray.length; ++x)
{
GL.Vertex3(x, fpsarray[x], gldepth);
}
GL.End();
}
GL.PopMatrix();
ScrollFPS();
}
}
//This will make our FPS scroll.
function ScrollFPS()
{
//To do so, we'll use this for loop.
for (var x = 1; x < fpsarray.length; ++x)
{
fpsarray[x - 1] = fpsarray [x];
}
//If our FPS is less than 1000....
if(fps < 1000)
{
//... we'll change the length to "Length - 1" and set it to our FPS.
fpsarray[fpsarray.length - 1] = fps;
}
}
//This function will be run if we're playing via a Mac.
static function IsDashboard()
{
return Application.platform == RuntimePlatform.OSXDashboardPlayer;
}
//This will be run if we're on a PC.
static function IsWindows()
{
return Application.platform == RuntimePlatform.WindowsPlayer;
}
//And finally, this function will run if we're playing via a web browser.
static function IsBrowser()
{
return(Application.platform == RuntimePlatform.WindowsWebPlayer ||
Application.platform == RuntimePlatform.OSXWebPlayer);
}
function LateUpdate()
{
//If either showfps or showfpsgraph is active...
if(showfps || showfpsgraph)
{
//...we'll run our FPSUpdate function.
FPSUpdate();
}
//If our escape key is pressed...
if(Input.GetKeyDown("escape"))
{
//...we'll check and see what state we need to run.
switch(currentPage)
{
case Page.None:
PauseGame();
break;
case Page.Main:
if(!IsBeginning())
{
UnPauseGame();
}
break;
default:
currentPage = Page.Main;
}
}
}
function OnGUI()
{
//If we have a skin...
if(skin != null)
{
//...we'll set it to GUI.skin.
GUI.skin = skin;
}
ShowStatNums();
ShowLegal();
//If our game is paused...
if(IsGamePaused())
{
//...We'll set our GUI color and...
GUI.color = statColor;
//...see what case should be run.
switch(currentPage)
{
case Page.Main:
PauseMenu();
break;
case Page.Options:
ShowToolbar();
break;
case Page.Credits:
ShowCredits();
break;
}
}
}
function ShowLegal()
{
//If the IsLegal function isn't up...
if(!IsLegal())
{
//Let's set it up.
GUI.Label(Rect(Screen.width - 100, Screen.height - 20, 90, 20),
"placeholdertext");
}
}
function IsLegal()
{
//We'll return our function. This is just a snippet, this function can be extended to have
//an actual web address.
return !IsBrowser();
}
private var toolbarInt:int = 0;
private var toolbarStrings:String[] = ["Audio", "Graphics", "Stats", "System"];
function ShowToolbar()
{
BeginPage(300, 300);
toolbarInt = GUILayout.Toolbar(toolbarInt, toolbarStrings);
//Next we'll set up a switch/case statement to see what we should do.
switch(toolbarInt)
{
case 0:
VolumeControl();
break;
case 1:
ShowDevice();
break;
case 2:
Qualities();
break;
case 3:
ShowDevice();
break;
}
//Now that we've done everything, we'll run our end page function.
EndPage();
}
//Next up is our credits page.
function ShowCredits()
{
BeginPage(300, 300);
//As long as there's still a credit left, we'll keep going.
for(var credit in credits)
{
GUILayout.Label(credit);
}
//We'll also continue to set our credits for each one in crediticons.
for(var credit in crediticons)
{
GUILayout.Label(credit);
}
//Now that we're done, end the page.
EndPage();
}
function ShowBackButton()
{
if(GUI.Button(Rect(20, Screen.height - 50, 50, 20), "Back"))
{
currentPage = Page.Main;
}
}
//This will show our device information.
function ShowDevice()
{
GUILayout.Label("Unity player version " + Application.unityVersion);
GUILayout.Label("Graphics: " + SystemInfo.graphicsDeviceName + " " +
SystemInfo.graphicsMemorySize + "MB\n" +
SystemInfo.graphicsDeviceVersion + "\n" +
SystemInfo.graphicsDeviceVendor);
GUILayout.Label("Shadows: " + SystemInfo.supportsShadows);
GUILayout.Label("Image Effects: " + SystemInfo.supportsImageEffects);
GUILayout.Label("Render Textures: " + SystemInfo.supportsRenderTextures);
}
function Qualities()
{
//Let's print out our quality label.
switch(QualitySettings.currentLevel)
{
case QualityLevel.Fastest:
GUILayout.Label("Fastest");
break;
case QualityLevel.Fast:
GUILayout.Label("Fast");
break;
case QualityLevel.Simple:
GUILayout.Label("Simple");
break;
case QualityLevel.Good:
GUILayout.Label("Good");
break;
case QualityLevel.Beautiful:
GUILayout.Label("Beautiful");
break;
case QualityLevel.Fantastic:
GUILayout.Label("Fantastic");
break;
}
}
//We'll let our user increase or decrease the quality level here.
function QualityControl()
{
GUILayout.BeginHorizontal();
//If our user hits the "Decrease" button...
if(GUILayout.Button("Decrease"))
{
//...we'll decrease the quality as per our user's wishes.
QualitySettings.DecreaseLevel();
}
//Conversely, if our "Increase" button is hit...
if(GUILayout.Button("Increase"))
{
//...we'll increase the quality.
QualitySettings.IncreaseLevel();
}
GUILayout.EndHorizontal();
}
//Now we'll set up our audio control.
function VolumeControl()
{
//Set up a label so our user knows what it is.
GUILayout.Label("Volume");
//And a slider for our user to adjust as needed.
AudioListener.volume = GUILayout.HorizontalSlider(AudioListener.volume, 0.0, 1.0);
}
//Next we'll set up a function to allow the user to toggle various controls.
function StatControl()
{
//We'll set up the layout and our toggles.
GUILayout.BeginHorizontal();
showfps = GUILayout.Toggle(showfps, "FPS");
showtris = GUILayout.Toggle(showtris, "Triangles");
showvtx = GUILayout.Toggle(showvtx, "Vertices");
showfpsgraph = GUILayout.Toggle(showfpsgraph, "FPS Graph");
GUILayout.EndHorizontal();
}
function FPSUpdate()
{
var delta = Time.smoothDeltaTime;
//If our game is not paused and our delta is not equal to 0...
if(!IsGamePaused delta != 0.0)
{
//...we'll set our fps to 1 divided by delta.
fps = 1/delta;
}
}
function ShowStatNums()
{
GUILayout.BeginArea(Rect(Screen.width - 100, 10, 100, 200));
//If we're showing our FPS....
if(showfps)
{
//...we'll set the properties and display it.
var fpsString = fps.ToString("#, ##0 fps");
GUI.color = Color.Lerp(lowFPSColor, highFPSColor, (fps - lowFPS)/(highFPS - lowFPS));
GUILayout.Label(fpsString);
}
//If we're showing either tris or verts...
if(showtris || showvtx)
{
//...we'll get our stats and set the color.
GetObjectStats();
GUI.color = statColor;
}
//If we're showing our tris...
if(showtris)
{
//...we'll make a label for the info and stick it in.
GUILayout.Label(tris + "tri");
}
//If we're showing our vertexes...
if(showvtx)
{
//....make a label and put the info inside.
GUILayout.Label(verts + "vtx");
}
GUILayout.EndArea();
}
//Our begin page function. By making this, we can avoid having to write the code with every page we have.
function BeginPage(width, height)
{
GUILayout.BeginArea(Rect((Screen.width - width)/2, (Screen.height - height)/2, width, height));
}
//Our end page function. By making this, we can avoid having to write the code with every page we have.
function EndPage()
{
GUILayout.EndArea();
//If our current page is not our main page....
if(currentPage != Page.Main)
{
ShowBackButton();
}
}
function IsBeginning()
{
return Time.time < startTime;
}
//Now we'll set up our main pause menu function.
function PauseMenu()
{
BeginPage(200, 200);
//If our button is pressed....
if(GUILayout.Button(IsBeginning() ? "Play":"Continue"))
{
//...we'll unpause the game.
UnPauseGame();
}
//If our options button is pressed...
if(GUILayout.Button("Options"))
{
//...we'll set our current page/navigate to the options page.
currentPage = Page.Options;
}
//If our credits button is pressed...
if(GUILayout.Button("Credits"))
{
//....we'll set our current page/navigate to the credits page.
currentPage = Page.Credits;
}
//If we're in the browser, not IsBeginning, and our restart button is pressed.....
if(IsBrowser() !IsBeginning GUILayout.Button("Restart"))
{
//...we'll open our url.
Application.OpenURL(url);
}
//Now we'll end the page.
EndPage();
}
//Next we'll create a function to get our object stats.
function GetObjectStats()
{
verts = 0;
tris = 0;
var ob = FindObjectsOfType(GameObject);
//For every object in our ob variable...
for(var obj in ob)
{
//...we'll get the stats of the object.
GetObjectStats(obj);
}
}
function GetObjectStats(object)
{
//Let's declare a variable for our filters and set it.
var filters:Component[];
filters = Object.GetComponentsInChildren(MeshFilter);
//For every MeshFilter we have in filters....
for(var f:MeshFilter in filters)
{
//...we'll get the tris and verts of it.
tris += f.sharedMesh.triangles.Length/3;
verts += f.sharedMesh.vertexCount;
}
}
//Now we'll set up the function we'll use to actually pause the game.
function PauseGame()
{
//We'll save our timeScale and then set it to 0.
savedTimeScale = Time.timeScale;
Time.timeScale = 0;
//We'll also pause our AudioListener.
AudioListener.pause = true;
//If we have a pauseFilter and it is enabled....
if(pauseFilter) pauseFilter.enabled = true;
//...then we'll set our current page to the main page.
currentPage = Page.Main;
}
//Now that we have our pause function, we'll naturally need a way to unpause. That's where this
//function comes in.
function UnPauseGame()
{
//To begin, we'll restore our timeScale to the previously saved timeScale.
Time.timeScale = savedTimeScale;
//Next we'll unpause our AudioListener.
AudioListener.pause = false;
//If we have a pauseFilter and it is disabled...
if(pauseFilter) pauseFilter.enabled = false;
//Our current page is set to none.
currentPage = Page.None;
//If it's the beginning and start is not null....
if(IsBeginning() start != null)
{
//...then start is active.
start.active = true;
}
}
//This function is run if we have our game paused.
function IsGamePaused()
{
//Since our game is paused, our timeScale is set to 0.
return Time.timeScale == 0;
}
function OnApplicationPause(pause:boolean)
{
//If our game is paused...
if(IsGamePaused())
{
//...we'll pause our AudioListener.
AudioListener.pause = true;
}
}
Not really a solution for Javascript, but I tried converting it to/using C# instead and it works. So while I’m still somewhat interested if anybody knows something I’m overlooking (I’ve tried the previous suggestion of testing piece by piece, and I still wasn’t able to pinpoint why it’s failing), it’s not really something that’s a priority now that I have a pause menu working.
Thanks to those that tried to help 