Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

UnifyCommunity PauseMenu

Discussion in 'Extensions & OnGUI' started by technicat, Jan 16, 2011.

  1. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    *** Updated to relocated links ***

    Almost long time ago, I implemented this pause menu to learn UnityGUI and put it on the Unity wiki:

    http://wiki.unity3d.com/index.php/PauseMenu

    Recently, I've been getting more emails and individual PM's with questions about this script. I'm pleased to discover the script is actually getting used, but I usually refer the questioners to this forum and http://answers.unity3d.com/ because I don't want be in the business of free individual programming support (I try to charge for that), and most of the questions really are general programming issues. So I'm starting this thread so users of this script can help each other out (perhaps even add functionality), and questions and answers don't have to be repeated (I've seen some people in the Unity forum and answers site help out, already -thanks!)

    I'll start off with some quick answers to some recent queries:

    "What are the terms of use?" - Do anything you want with it.

    "I'm getting an error with the SepiaToneFilter" - Image effects including the sepia tone filter are a Unity Pro feature - just comment out the that line in the script.

    "When the game is paused, keyboard input still comes through." - Look at the definition of PauseGame, it pauses time and the audio listener. If all input was disabled, you couldn't operate the menu! Add the appropriate code to your input-handling scripts, e.g. check if the timescale is zero.

    "How do I use this on an iPhone" - this script was only used for Unity webplayers, so if you want to use it on an iPhone, you'll have to change the OnGUI function, at the very least replace the Input.GetKeyDown check with something appropriate for how you want to invoke the menu.

    Before asking any questions, please acquaint yourself with the UnityGUI functions (there's a walkthrough in the Unity manual) and try to understand how the pause menu script works. I wrote a general breakdown of the script here (moved to Medium):

    https://medium.com/technicat-on-software/don-t-use-this-pause-menu-572ea107c383
     
    Last edited: Sep 30, 2016
  2. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    I should mention the C# version of the PauseMenu on the wiki was contributed by someone else.
     
  3. cortex

    cortex

    Joined:
    Dec 21, 2010
    Posts:
    8
    I'm currently creating a FPS game. I need to create a pause button for my pause menu. I've found an excellent pause script here: http://www.unifycommunity.com/wiki/index.php?title=PauseMenu
    I'm currently using the free version of Unity3D. I was able to get the pause script working within the game when I first start the game.
    On the PC, press ESC key reloads the pause menu.
    My questions is, how do I create a button or text link which reloads the Pause menu on screen for an iPhone device?
    Any help is appreciated, Thank you
     
  4. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Look in the OnGUI function, replace the check for the ESC key with something appropriate, e.g. you can place another UnityGUI button for "Pause". That should be straightforward if you've gone through the UnityGUI walkthrough in the Unity manual.
     
  5. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    I encourage users of this pause menu to also consider GUIKit and EZGUI from http://gameassets.net/ and http://anbsoft.com/ respectively. I haven't used either of them, but from what I've seen in their discussion threads on this forum, they provide a lot of support for the price.
     
  6. Teriki Tora

    Teriki Tora

    Joined:
    May 21, 2010
    Posts:
    132
    I'm currently working on using the GameHUD script's code to get the script to scale correctly: (from Lerpz tutorial)
    Code (csharp):
    1. // Our GUI is laid out for a 1920 x 1200 pixel display (16:10 aspect). The next line makes sure it rescales nicely to other resolutions.
    2.     GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (Screen.height / nativeVerticalResolution, Screen.height / nativeVerticalResolution, 1));
    My font scales nicely whenever I use this, and also scales my images very nicely, but when I use the pause script in the nude (no changes) everything changes sizes when I alter the screen size. In other words the buttons don't scale, the positioning doesn't scale, and my font especially doesn't scale. I need the GUI to scale depending on monitor/window size in order to incorporate a wider audience.

    $GuiProb.jpg

    Small screen, BIG PAUSE MENU

    $GuiProb2.jpg

    BIG SCREEN, small pause menu

    Notice how my HUD items scale nicely with the screen, but the pause menu does not. I don't know how to work the script correctly (or well enough) to get the code shown above to work correctly (If I add it, the buttons and words scale right, but it's lop-sided and no longer centered)
     
  7. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    I'm not that familiar with the Lerpz code or with GUI.matrix for that matter (although there's a discussion here - http://forum.unity3d.com/threads/68285-Unity-3-causes-GUI.Button-to-be-much-smaller ) but I'm guessing the problem is that the PauseMenu is trying to take the screen size into account for positioning and so using GUI.matrix to apply another adjustment for screen size will mess up that positioning. Try changing the BeginPage function to just use the same hardcoded screensize that you're supplying to GUI.matrix (instead of Screen.width and height)
     
  8. Teriki Tora

    Teriki Tora

    Joined:
    May 21, 2010
    Posts:
    132
    I've currently gotten it to scale correctly with the default Lerpz tutorial size. The only thing I can't get to scale at the moment is the positions (like the offsets). Though surprisingly, just by switching a few values I've gotten it to scale and to position vertically correctly. I'll actually give you the altered script with the scaling ability once I figure it all out. Right now I've only got about half of it figured out and will need some time to figure out the rest.

    EDIT:

    I have figured it out and scaled all of the buttons and components to fit... ANY SCREEN

    Here you go Technicat ^^

    BTW, I had my own legal information in the code, so I stripped it out and replaced it with dummy information, you can put your information back in. Also the "Begin Paused" code stuff was taken out for my own purposes, but the concept remains the same.
    Code (csharp):
    1.  
    2. var skin:GUISkin;
    3.  
    4.  
    5. private var gldepth = -0.5;
    6. private var startTime = 0.1;
    7.  
    8. var nativeVerticalResolution = 1200.0;
    9. var scaledResolutionWidth = nativeVerticalResolution / Screen.height * Screen.width;
    10.  
    11. var mat:Material;
    12.  
    13. private var tris = 0;
    14. private var verts = 0;
    15. private var savedTimeScale:float;
    16. private var pauseFilter;
    17.  
    18. private var showfps:boolean;
    19. private var showtris:boolean;
    20. private var showvtx:boolean;
    21. private var showfpsgraph:boolean;
    22.  
    23. var lowFPSColor = Color.red;
    24. var highFPSColor = Color.green;
    25.  
    26. var lowFPS = 30;
    27. var highFPS = 50;
    28.  
    29. var start:GameObject;
    30.  
    31. var url = "unity.html";
    32.  
    33. var statColor:Color = Color.yellow;
    34. var GuiColor:Color = Color.white;
    35.  
    36. var credits:String[]=[
    37.     "Credits This stuff",
    38.     "I put a Catchphrase here haha",
    39.     "Programming by Me!",
    40.     "Copyright (c) 100BC-2011"] ;
    41. var crediticons:Texture[];
    42.  
    43. enum Page {
    44.     None,Main,Options,Credits
    45. }
    46.  
    47. private var currentPage:Page;
    48.  
    49. private var fpsarray:int[];
    50. private var fps:float;
    51.  
    52. function Start() {
    53.     fpsarray = new int[scaledResolutionWidth];
    54.     Time.timeScale = 1.0;
    55.     //pauseFilter = Camera.main.GetComponent(SepiaToneEffect);
    56.     //PauseGame();
    57. }
    58.  
    59. function OnPostRender() {
    60.     if (showfpsgraph  mat != null) {
    61.         GL.PushMatrix ();
    62.         GL.LoadPixelMatrix();
    63.         for (var i = 0; i < mat.passCount; ++i)
    64.         {
    65.             mat.SetPass(i);
    66.             GL.Begin( GL.LINES );
    67.             for (var x=0; x<fpsarray.length; ++x) {
    68.                 GL.Vertex3(x,fpsarray[x],gldepth);
    69.             }
    70.         GL.End();
    71.         }
    72.         GL.PopMatrix();
    73.         ScrollFPS();
    74.     }
    75. }
    76.  
    77. function ScrollFPS() {
    78.     for (var x=1; x<fpsarray.length; ++x) {
    79.         fpsarray[x-1]=fpsarray[x];
    80.     }
    81.     if (fps < 1000) {
    82.         fpsarray[fpsarray.length-1]=fps;
    83.     }
    84. }
    85.  
    86. static function IsDashboard() {
    87.     return Application.platform == RuntimePlatform.OSXDashboardPlayer;
    88. }
    89.  
    90. static function IsBrowser() {
    91.     return (Application.platform == RuntimePlatform.WindowsWebPlayer ||
    92.         Application.platform == RuntimePlatform.OSXWebPlayer);
    93. }
    94.  
    95. function LateUpdate () {
    96.     if (showfps || showfpsgraph) {
    97.         FPSUpdate();
    98.     }
    99.     if (Input.GetKeyDown("escape")) {
    100.         switch (currentPage) {
    101.             case Page.None: PauseGame(); break;
    102.             case Page.Main: UnPauseGame(); break;
    103.             default: currentPage = Page.Main;
    104.         }
    105.     }
    106. }
    107.  
    108. function OnGUI () {
    109.     if (skin != null) {
    110.         GUI.skin = skin;
    111.     }
    112.     //Our GUI is laid out for a 1920 x 1200 pixel display (16:10 aspect). The next line makes sure it rescales nicely to other resolutions.
    113.     GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (Screen.height / nativeVerticalResolution, Screen.height / nativeVerticalResolution, 1));
    114.    
    115.     ShowStatNums();
    116.     ShowLegal();
    117.     if (IsGamePaused()) {
    118.         GUI.color = GuiColor;
    119.         switch (currentPage) {
    120.             case Page.Main: PauseMenu(); break;
    121.             case Page.Options: ShowToolbar(); break;
    122.             case Page.Credits: ShowCredits(); break;
    123.         }
    124.     }  
    125. }
    126.  
    127. function ShowLegal() {
    128.     if (!IsLegal()) {
    129.         GUI.Label(Rect(scaledResolutionWidth-100,nativeVerticalResolution-20,scaledResolutionWidth/4,nativeVerticalResolution/4),
    130.         "MyWebsite.com");
    131.     }
    132. }
    133.  
    134. function IsLegal() {
    135.     return !IsBrowser() ||
    136.     Application.absoluteURL.StartsWith("http://MyWebsite.com/") ||
    137.     Application.absoluteURL.StartsWith("http://MyWebsite.com/");
    138. }
    139.  
    140. private var toolbarInt:int=0;
    141. private var toolbarStrings: String[]= ["Audio","Graphics","Stats","System"];
    142.  
    143. function ShowToolbar() {
    144.     BeginPage(1000,600);
    145.     toolbarInt = GUILayout.Toolbar (toolbarInt, toolbarStrings);
    146.     switch (toolbarInt) {
    147.         case 0: VolumeControl(); break;
    148.         case 3: ShowDevice(); break;
    149.         case 1: Qualities(); QualityControl(); break;
    150.         case 2: StatControl(); break;
    151.     }
    152.     EndPage();
    153. }
    154.  
    155. function ShowCredits() {
    156.     BeginPage(600,600);
    157.     for (var credit in credits) {
    158.         GUILayout.Label(credit);
    159.     }
    160.     for (var credit in crediticons) {
    161.         GUILayout.Label(credit);
    162.     }
    163.     EndPage();
    164. }
    165.  
    166. function ShowBackButton() {
    167.     if (GUI.Button(Rect(40,nativeVerticalResolution-100,200,80),"Back")) {
    168.         currentPage = Page.Main;
    169.     }
    170. }
    171.  
    172.  
    173. function ShowDevice() {
    174.     GUILayout.Label ("Unity player version "+Application.unityVersion);
    175.     GUILayout.Label("Graphics: "+SystemInfo.graphicsDeviceName+" "+
    176.     SystemInfo.graphicsMemorySize+"MB\n"+
    177.     SystemInfo.graphicsDeviceVersion+"\n"+
    178.     SystemInfo.graphicsDeviceVendor);
    179.     GUILayout.Label("Shadows: "+SystemInfo.supportsShadows);
    180.     GUILayout.Label("Image Effects: "+SystemInfo.supportsImageEffects);
    181.     GUILayout.Label("Render Textures: "+SystemInfo.supportsRenderTextures);
    182. }
    183.  
    184. function Qualities() {
    185.     switch (QualitySettings.currentLevel) {
    186.         case QualityLevel.Fastest:
    187.         GUILayout.Label("Fastest");
    188.         break;
    189.         case QualityLevel.Fast:
    190.         GUILayout.Label("Fast");
    191.         break;
    192.         case QualityLevel.Simple:
    193.         GUILayout.Label("Simple");
    194.         break;
    195.         case QualityLevel.Good:
    196.         GUILayout.Label("Good");
    197.         break;
    198.         case QualityLevel.Beautiful:
    199.         GUILayout.Label("Beautiful");
    200.         break;
    201.         case QualityLevel.Fantastic:
    202.         GUILayout.Label("Fantastic");
    203.         break;
    204.     }
    205. }
    206.  
    207. function QualityControl() {
    208.     GUILayout.BeginHorizontal();
    209.     if (GUILayout.Button("Decrease")) {
    210.         QualitySettings.DecreaseLevel();
    211.     }
    212.     if (GUILayout.Button("Increase")) {
    213.         QualitySettings.IncreaseLevel();
    214.     }
    215.     GUILayout.EndHorizontal();
    216. }
    217.  
    218. function VolumeControl() {
    219.     GUILayout.Label("Volume");
    220.     AudioListener.volume = GUILayout.HorizontalSlider(AudioListener.volume,0.0,1.0);
    221. }
    222.  
    223. function StatControl() {
    224.     GUILayout.BeginHorizontal();
    225.     showfps = GUILayout.Toggle(showfps,"FPS");
    226.     showtris = GUILayout.Toggle(showtris,"Triangles");
    227.     showvtx = GUILayout.Toggle(showvtx,"Vertices");
    228.     showfpsgraph = GUILayout.Toggle(showfpsgraph,"FPS Graph");
    229.     GUILayout.EndHorizontal();
    230. }
    231.  
    232. function FPSUpdate() {
    233.     var delta = Time.smoothDeltaTime;
    234.         if (!IsGamePaused()  delta !=0.0) {
    235.             fps = 1 / delta;
    236.         }
    237. }
    238.  
    239. function ShowStatNums() {
    240.     GUILayout.BeginArea(Rect(scaledResolutionWidth-200,20,scaledResolutionWidth/4,nativeVerticalResolution/4));
    241.     if (showfps) {
    242.         var fpsString= fps.ToString ("#,##0 fps");
    243.         GUI.color = Color.Lerp(lowFPSColor, highFPSColor,(fps-lowFPS)/(highFPS-lowFPS));
    244.         GUILayout.Label (fpsString);
    245.     }
    246.     if (showtris || showvtx) {
    247.         GetObjectStats();
    248.         GUI.color = statColor;
    249.     }
    250.     if (showtris) {
    251.         GUILayout.Label (tris+"tri");
    252.     }
    253.     if (showvtx) {
    254.         GUILayout.Label (verts+"vtx");
    255.     }
    256.     GUILayout.EndArea();
    257. }
    258.  
    259. function BeginPage(width,height) {
    260.     scaledResolutionWidth = nativeVerticalResolution / Screen.height * Screen.width;
    261.     GUILayout.BeginArea(Rect(scaledResolutionWidth/2 - (width/2), nativeVerticalResolution/2 - (height/2),width,height));
    262. }
    263.  
    264. function EndPage() {
    265.     GUILayout.EndArea();
    266.     if (currentPage != Page.Main) {
    267.         ShowBackButton();
    268.     }
    269. }
    270.  
    271. /*function IsBeginning() {
    272.     return Time.time < startTime;
    273. }*/
    274.  
    275.  
    276. function PauseMenu() {
    277.     BeginPage(800,300);
    278.     if (GUILayout.Button ("Continue")) {
    279.         UnPauseGame();
    280.  
    281.     }
    282.     if (GUILayout.Button ("Options")) {
    283.         currentPage = Page.Options;
    284.     }
    285.     if (GUILayout.Button ("Credits")) {
    286.         currentPage = Page.Credits;
    287.     }
    288.     if (IsBrowser()  GUILayout.Button ("Restart")) {
    289.         Application.OpenURL(url);
    290.     }
    291.     EndPage();
    292. }
    293.  
    294. function GetObjectStats() {
    295.     verts = 0;
    296.     tris = 0;
    297.     var ob = FindObjectsOfType(GameObject);
    298.     for (var obj in ob) {
    299.         GetObjectStats(obj);
    300.     }
    301. }
    302.  
    303. function GetObjectStats(object) {
    304.     var filters : Component[];
    305.     filters = object.GetComponentsInChildren(MeshFilter);
    306.     for( var f : MeshFilter in filters )
    307.     {
    308.         tris += f.sharedMesh.triangles.Length/3;
    309.       verts += f.sharedMesh.vertexCount;
    310.     }
    311. }
    312.  
    313. function PauseGame() {
    314.     savedTimeScale = Time.timeScale;
    315.     Time.timeScale = 0;
    316.     AudioListener.pause = true;
    317.     if (pauseFilter) pauseFilter.enabled = true;
    318.     currentPage = Page.Main;
    319.     TurnCharCamera.gameIsPaused = true;
    320. }
    321.  
    322. function UnPauseGame() {
    323.     Time.timeScale = savedTimeScale;
    324.     AudioListener.pause = false;
    325.     if (pauseFilter) pauseFilter.enabled = false;
    326.     currentPage = Page.None;
    327.     if (start != null) {
    328.         start.active = true;
    329.     }
    330.     TurnCharCamera.gameIsPaused = false;
    331. }
    332.  
    333. function IsGamePaused() {
    334.     return Time.timeScale==0;
    335. }
    336.  
    337. function OnApplicationPause(pause:boolean) {
    338.     if (IsGamePaused()) {
    339.         AudioListener.pause = true;
    340.     }
    341. }
    342.  
     
    Last edited: Jan 23, 2011
  9. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Nice! FYI, here's a bug report I submitted about UnityGUI not being resolution-independent (which only occurred to me after I started supporting Retina displays) - http://intra.unity3d.com/fogbugz/default.asp?374624_ika6

    In my more recent (and messier) versions of the pause menu, I have a boolean to toggle the start-paused behavior, something like this:

    Code (csharp):
    1.  
    2. public var startPaused=true;
    3.  
    and later

    Code (csharp):
    1.  
    2. if (startPaused) {
    3.  PauseGame()
    4. }
    5.  
    It would also be nice to have an #if UNITY_PRO wrapped around the pauseFilter use, if there was such a define.
     
    Last edited: Jan 23, 2011
  10. Teriki Tora

    Teriki Tora

    Joined:
    May 21, 2010
    Posts:
    132
    Just thought of this, this morning. What if you used one of the Unity Pro variables from the Stats screen?
    To determine if the Unity Player is a Pro version or not? If the Unity player doesn't support shadows then it's not Unity Pro, correct? That could be a good way around determining if it's UnityPro or not.
     
  11. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Checking for image effects sounds like a good idea, maybe

    Code (csharp):
    1.  
    2. if (SystemInfo.supportsImageEffects) {
    3.   pauseFilter = Camera.main.GetComponent(SepiaToneEffect);
    4. }
    5.  
    but it's a runtime check so that doesn't help people who are running Unity Indie and don't understand why they're getting a compile error on SepiaToneEffect.
     
    Last edited: Jan 24, 2011
  12. BSVALVE

    BSVALVE

    Joined:
    Jun 24, 2010
    Posts:
    35
    Hi technicat,

    I been using your pause menu for my game. I noticed that even my game had paused with the script but eventually I cannot stop my player from shooting while paused... So may I know how should I make a complete paused with your script please?


    Thanks and regards,
     
  13. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    The script pauses the game by setting Time.timeScale to zero:

    http://unity3d.com/support/documentation/ScriptReference/Time-timeScale.html

    This will pause any code that depends on the passage of time, including Unity physics, animation, but it doesn't stop all code from executing at all, of course, including input functions, otherwise you wouldn't be able to operate the pause menu. This all depends on your code, but I think the easiest thing to do is probably find where you're detecting the input for shooting, then wrap an "if (Time.timeScale>0)" around either the fire input detection or fire input execution so that it only happens if the game is not paused.

    There are many other approaches - if you search for "pause menu" in the forums, you'll see some advocating setting up a game controller where you can query an IsPaused function and there is are a couple of other pause menus on the Unity Asset Store, one of which actively goes through and disables other scripts. But checking Time.timeScale is what I do.
     
    Last edited: Apr 30, 2011
  14. BSVALVE

    BSVALVE

    Joined:
    Jun 24, 2010
    Posts:
    35

    Thanks for these advised I found the clue yeah! You're cheerful thanks again.
     
  15. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    I just remembered, the pause menu script has an IsGamePaused function, which just checks if Time.timeScale is zero. So if you want to make the code look a little bit cleaner, instead of checking Time.timeScale directly, you could make IsGamePaused static so, for example if the pausemenu script is name PauseMenu, you can call PauseMenu.IsGamePaused()
     
  16. BSVALVE

    BSVALVE

    Joined:
    Jun 24, 2010
    Posts:
    35
    I really found the cure for this particular coding myth please be peace I really have to thanks for your advised cuz this took me 1 week to figured out and ask many too.

    Thanks technicat. Sweet for you^_^
     
  17. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,527
    Hi Technicat, I notice that when you go to the options page using this, the Audio button seems to be stuck on? Like for eg go to options, then click(touch) the other buttons and observe the visual state of the audio button.

    Using a custom style I am pressing the other buttons and the audio button is behaving visually as though it were pressed. Any ideas?

    Thanks
    AaronC
     
  18. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    This is only with a custom style? (I don't see it with the default skin) Are you assigning a skin to the Skin property in the script or supplying the style by passing additional arguments to the GUI.toolbar call in the script? Either way, I would try to narrow down which style property is the one that's showing up and if it appears to be behaving incorrectly, submit it to Unity as a bug report.
     
  19. fourpixel

    fourpixel

    Joined:
    Dec 30, 2011
    Posts:
    7
    Thanks !
     
    Last edited: Jan 30, 2012
  20. mojojojo

    mojojojo

    Joined:
    Dec 16, 2009
    Posts:
    138
    I've been trying to use this but it's not pausing the camera view. How do I get the FPS motion to be paused by this?
     
  21. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    As the original post states, this pause script does not automatically disable input, so you need to go into your FPS script, and add some code in the appropriate section that checks if the game is paused.
     
  22. toastt

    toastt

    Joined:
    Mar 16, 2012
    Posts:
    3
    technicat,

    Thank you for making your pause menu available to the community!
    I've started using it in my prototypes and have noticed you've included some legal credits on the bottom corner of the game in real builds.
    I'd like to credit you (and all of the authors who's code I've built on) in an extended credit page but not on the screen while the game is running. I'm not shipping with your code, and I won't use it for profit.
     
  23. toastt

    toastt

    Joined:
    Mar 16, 2012
    Posts:
    3
    Also on a quick note, the warnings in 3.5 in the Qualities() function can be silenced by rewriting it as:

    Code (csharp):
    1. void Qualities() {
    2.     GUILayout.Label(QualitySettings.names[QualitySettings.GetQualityLevel()]);
    3. }
     
  24. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Thanks! You should feel free to ship the code, though. And any hardcoded credit info I left in the script is just for example purposes - it's meant to be replaced or commented out however you like. If you're referring to the URL that's displayed on-screen by the ShowLegal function, that's just a very minimal anti-piracy check for webplayers, so if someone copied one of my webplayers it would at least show my web site name. You can just comment that out if you don't need it.

    Edit: And feel free to try to make a profit!
     
    Last edited: Mar 16, 2012
  25. toastt

    toastt

    Joined:
    Mar 16, 2012
    Posts:
    3
    Ah, that makes perfect sense! Glad one of us is thinking about these things.
    Thanks again!
     
  26. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Thanks for that tip, by the way. I made the change to version on the wiki (just the JS version) and to the one I have on the Asset Store (from the latest review apparently I have some Unity 3.5 breakage). I see there's a complaint on the wiki that it doesn't work on iOS. It's not really suitable for mobile, but it could use a #pragma strict added to it and a thorough cleanup of the resulting errors.
     
  27. Rhys_Pieces

    Rhys_Pieces

    Joined:
    Feb 13, 2012
    Posts:
    1
    I have tried using this code but getting some errors.

    Assets/Scripts/Options.js(234,48): BCE0051: Operator '/' cannot be used with a left hand side of type 'Object' and a right hand side of type 'int'.
    Assets/Scripts/Options.js(278,22): BCE0019: 'GetComponentsInChildren' is not a member of 'Object'.
    Assets/Scripts/Options.js(290,34): BCE0019: 'enabled' is not a member of 'Object'.
    Assets/Scripts/Options.js(297,34): BCE0019: 'enabled' is not a member of 'Object'.
     
  28. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    I would only expect to see those compiler errors if you're building to mobile or if #pragma strict is added to the script (unless Unity 3.5 has gotten a lot stricter), but you should be able to resolve them even in those cases by adding the appropriate type declarations to the variables in question, e.g. I think the second warning you list is in the GetObjectStats function (double click on the error should bring you to that code) and, assuming GetComponentsInChildren is a member function of GameObject (you can check the Script Reference to make sure) then change GetObjectStats(object) to GetObjectStats(object:GameObject), and do something similar for the other errors.
     
  29. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    If you like the convenience of downloading from the Asset Store or feel like contributing to my avoid-getting-a-real-job fund, I have a version of the pause menu on the Asset Store now for $2:

    http://u3d.as/content/technicat-llc/fugu-pause/32h

    It has the Pro-dependent code commented out and fixed to work with #pragma strict on, which should help if anyone wants to try running it on mobile (not that I recommend it), and at least one feature that didn't make it onto the wiki version, I think - an option to turn on cursor locking. Maybe I'll add an optional pause button since that's been a common request. Anyone is welcome to make those types of changes to the wiki version, by the way, but I'm going to leave that one alone.
     
  30. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Also, the C# version that was contributed to the wiki may work better.
     
  31. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    I'm trying to get familiar with git and github, so I put the pause menu on it:

    https://github.com/technicat/FuguPause

    This version currently matches the one I have on the Asset Store, so it's got Pro features commented out (which makes the code look a little messy) and it's got #pragma strict set so that it has a better chance of working on mobile (not that I recommend it). If you need it to scale I suggest trying out what Teriki Tora did above. And thanks to toastt for the Qualities fix! So if you're into git, go ahead and fork and modify the project!
     
  32. Benifir

    Benifir

    Joined:
    Oct 5, 2012
    Posts:
    22
    This script works great! I've yet to put in a camera pause feature. Now here are my questions, how can I change the textbox/font color, make the boxes larger and in the center of the screen, and put a simple all black background instead of seeing the game? I'm just a 3D artist so programming isn't my specialty.
     
  33. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    You can change the appearance of the GUI elements by dragging a GUISkin into the skin variable (look in the OnGUI function and you'll see the GUI skin is set). I have a breakdown of the code on http://drupal.technicat.com/games/unity/unitygui/pausemenu.html which actually uses the free Necromancer skin from the Asset Store in the screenshots, and you might also want to check out the Extra GUI Skins package, which you can use as a starting point and tweak and give you an idea how to create your own. I recommend first reading the UnityGUI intro in the Unity Manual - it's actually one of the more comprehensive pieces of doc there and will show you how styles and skins and layout, etc. work.

    Once you've got a handle on that, you can tweak the calls to BeginPage or even the BeginPage function itself to adjust the placement, since that code just tries to center the menu on the screen. As for turning the screen black, you can add anything to the PauseGame/UnPauseGame functions - just off the top of my head, you could activate a full-screen black GUITexture, or use GL calls to draw a black fullscreen quad, or maybe the easiest thing is to clear the camera's visibility/culling mask (I forget what it's called exactly, but check the script reference for Camera).
     
  34. Rovalin

    Rovalin

    Joined:
    Sep 15, 2012
    Posts:
    2
    Thank you so much for having this code up! It's just what I was looking for. I had one question though. How do I customize it? Like, how would I change the text and maybe add a background? Thanks you SO much again!
    -Rov
     
  35. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    You can do a text search in the script file to find the text you want to change, and then just change it. But most of it is exposed in public variables, so you should be able to change them in the inspector. Generally, if you want to customize a script, you need to understand it - check out the link to the code walkthrough at the bottom of the first post of this thread. As mentioned there in the previous post, you can also change the appearance by supplying a GUISkin, which you should also read up on in the Unity manual.
     
  36. Rovalin

    Rovalin

    Joined:
    Sep 15, 2012
    Posts:
    2
    I will be sure to check that out. Thanks for the quick reply!
    -Rov
     
  37. JeffAndre

    JeffAndre

    Joined:
    Apr 14, 2013
    Posts:
    1
    ALGUEM AJUDA? DA ESSE ERRO E NÂO APARECE O MENU Font size and style overrides are only supported for dynamic fonts.
     
  38. sgPwnZone

    sgPwnZone

    Joined:
    Jun 8, 2013
    Posts:
    3
    I know it's been quite a while since anyone has posted to this thread, but I have a question.
    Can you walk me through the process of keeping my characters head from turning while the pause menu is active? I know someone else asked something related to that, but you didn't give a very straight forward answer.
     
    Last edited: Jun 17, 2013
  39. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,527
    Hi there.

    That implies that there is a "public variable" that should look like this at the top of your script:

    var TurnCharCamera: GameObject;

    or
    var TurnCharCamera: Camera;

    If the code says "active=false; (or true)" you need the first version of the variable above at the top of your script

    and if it says enabled=true; (or false) you need the second type of var above.

    Once youve added that and saved your script, you will need to drag a camera or object with a camera from hieracy view into the new "slot" that has appeared in the script you just modified.

    Hope thats helpful
    ~A
     
  40. sgPwnZone

    sgPwnZone

    Joined:
    Jun 8, 2013
    Posts:
    3
    Thanks Aaron C, but I fixed it a different way.

    I have now encountered a different problem.
    I ended up using a modified version of technicat's pause menu that I got off a different site. I also created a main-menu, and there is a button on the pause menu that says "return to main menu" This all works great, but there is one problem. If i load the game, click "play" on the main menu, then pause the game, click return to main menu, and then click Play again, My player can no longer move. He can lood up and down, left and right, and he can turn his flashlight on and off, but he cannot move around. Please help, this is the coding, (by the way I have the Player controlling both the X and Y axis of the mouse, not the main camera.

    var skin : GUISkin;
    var buttonOutlineAndTextColor = Color.white;
    var creditIcons : Texture[];
    var credits : String[] = ["Team Free Range."];
    var loadMainMenu : String;

    private var savedTimeScale : float;
    private var pauseFilter;
    private var currentPage : Page;
    private var toolbarInt : int = 0;
    private var toolbarStrings : String[] = ["Audio", "Graphics"];
    private var firstPersonControllerCamera;

    enum Page
    {
    None, Main, Options, Credits
    }

    function Start()
    {
    Screen.showCursor = false;
    Screen.lockCursor = true;
    }

    function LateUpdate()
    {
    if (Input.GetKeyDown("escape"))
    {
    switch (currentPage)
    {
    case Page.None : PauseGame();
    break;

    case Page.Main : UnPauseGame();
    break;

    default : currentPage = Page.Main;
    }
    }
    }

    function OnGUI()
    {
    if (skin != null)
    {
    GUI.skin = skin;
    }

    if (IsGamePaused())
    {
    GUI.color = buttonOutlineAndTextColor;

    switch (currentPage)
    {
    case Page.Main: PauseMenu();
    break;

    case Page.Options: ShowToolbar();
    break;

    case Page.Credits: ShowCredits();
    break;
    }
    }
    }

    function ShowToolbar()
    {
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");

    BeginPage(400, 200);

    toolbarInt = GUILayout.Toolbar (toolbarInt, toolbarStrings);

    switch (toolbarInt)
    {
    case 0 : VolumeControl();
    break;

    case 1 : Qualities();
    QualityControl();
    break;
    }

    if (GUILayout.Button("Back"))
    {
    currentPage = Page.Main;
    }

    EndPage();
    }

    function ShowCredits()
    {
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");

    BeginPage(400, 200);

    for (var credit in credits)
    {
    GUILayout.Label(credit);
    }

    for (var credit in creditIcons)
    {
    GUILayout.Label(credit);
    }

    if (GUILayout.Button("Back"))
    {
    currentPage = Page.Main;
    }

    EndPage();
    }

    function Qualities()
    {
    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;
    }
    }

    function QualityControl()
    {
    GUILayout.BeginHorizontal();

    if (GUILayout.Button("Decrease"))
    {
    QualitySettings.DecreaseLevel();
    }

    if (GUILayout.Button("Increase"))
    {
    QualitySettings.IncreaseLevel();
    }

    GUILayout.EndHorizontal();
    }

    function VolumeControl()
    {
    GUILayout.Label("Use the slider to adjust the volume. Note that the volume is defaulted at 100%.");
    AudioListener.volume = GUILayout.HorizontalSlider(AudioListener.volume, 0.0, 1.0);
    }

    function BeginPage(width, height)
    {
    GUILayout.BeginArea(Rect((Screen.width - width) / 2, (Screen.height - height) / 2, width, height));
    }

    function EndPage()
    {
    GUILayout.EndArea();
    }

    function PauseMenu()
    {
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");
    GUI.Box(Rect(0, 0, Screen.width, Screen.height), "");

    BeginPage(400, 200);

    if (GUILayout.Button ("Continue"))
    {
    UnPauseGame();
    }

    if (GUILayout.Button ("Settings"))
    {
    currentPage = Page.Options;
    }

    if (GUILayout.Button ("Credits"))
    {
    currentPage = Page.Credits;
    }

    if (GUILayout.Button ("Quit to Main Menu"))
    {
    Application.LoadLevel(0);
    }

    EndPage();
    }

    function PauseGame()
    {
    savedTimeScale = Time.timeScale;
    Time.timeScale = 0;
    AudioListener.pause = true;
    firstPersonControllerCamera = gameObject.Find("Player").GetComponent("MouseLook");
    firstPersonControllerCamera.enabled = false;
    Screen.showCursor = true;
    Screen.lockCursor = false;
    if (pauseFilter)
    {
    pauseFilter.enabled = true;
    }

    currentPage = Page.Main;
    }

    function UnPauseGame()
    {
    Time.timeScale = savedTimeScale;
    AudioListener.pause = false;
    firstPersonControllerCamera.enabled = true;
    Screen.showCursor = false;
    Screen.lockCursor = true;

    if (pauseFilter)
    {
    pauseFilter.enabled = false;
    }

    currentPage = Page.None;
    }

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

    function OnApplicationPause (pause : boolean)
    {
    if (IsGamePaused())
    {
    AudioListener.pause = true;
    }
    }
     
  41. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    @sgnPwnZone, I see you're loading a different level to bring up the main menu, so you probably want to call UnPauseGame before doing that, to restore the cursor and Time settings, first.
     
  42. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Yet another version of this pause menu is on http://learnunity4.com/ as part of an example project in an upcoming book on Unity iOS. It's a simpler version (e.g. the stats functions are removed) but it does have some scaling code similar to the changes made by Teriki Tora in this thread.
     
  43. Play_Edu

    Play_Edu

    Joined:
    Jun 10, 2012
    Posts:
    715
    Awwwwwwwwwwwesssssssssssssssssssssm man
     
  44. Halo500

    Halo500

    Joined:
    Apr 24, 2013
    Posts:
    37
    Hi technicat! I am currently making a game on Android, and I am implying your PauseMenu Script from the wiki page (the C# version) and I already created my own Main Menu, so how would I get rid of yours in the script? If I try to take away MainPauseMenu, the escape button won't work anymore...
     
  45. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Sorry, not quite sure what you're saying - what's MainPauseMenu? If you don't want the pause menu to start up immediately, you can remove the call to PauseGame that's in the Start callback (in some other versions of the script, I make that an option by having a public boolean startPaused variable and checking that before calling PauseGame in Start).
     
  46. Halo500

    Halo500

    Joined:
    Apr 24, 2013
    Posts:
    37
    Sorry, I wasn't being clear enough.

    I'm trying to add your script into my game, the in-game level itself. I already have my own main menu, gui buttons and all of that. I love the way your pause menu works, with the volume bar and all (I am still new to scripting) and I just want it to be attached to the MainCamera of my Player and when I press "escape" the pause menu would show.

    My problem is that I don't need the included main menu, and if I remove it, the pause menu won't show up anymore. It seems to only pop up when I actually click "Play" on your main menu gui buttons. I would really like a simple way to just remove the main menu buttons and to fix this. Since you were the creator of this amazing script, I was thinking I'd come to you for help. :)
     
  47. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    Oh, I see what you mean. Well, the OnGUI callback checks which menu page/screen is supposed to be displayed, and if it's Page.Main then it calls PauseMenu to display the main menu. So you could start by rewriting PauseMenu to show your own main menu or replace the call to PauseMenu with a call to your own function. And then if you don't need the other pages, you can remove them as a cleanup phase (and remove/customize the Page enums as you like).
     
  48. DryTear

    DryTear

    Joined:
    Nov 30, 2012
    Posts:
    312
    for muting sound and enibling sound, i would highly recomming doing something like this :

    Code (csharp):
    1.  
    2. static var isAudioMuted : boolean = false;
    3.  
    4. function Update()
    5. {
    6.     if(isAudioMuted == true)
    7.     {
    8.          GameObject.Find("Main Camera").GetComponent("AudioListener").enabled = false;
    9.     }
    10.     else
    11.     {
    12.         GameObject.Find("Main Camera").GetComponent("AudioListener").enabled = false;
    13.     }
    14. }
    15.  
    Then on your pause menu script,

    Code (csharp):
    1.  
    2. if(GUI.Button("MuteSound"))
    3. {
    4.     GameObject.Find("AudioManager").GetComponent("AudioCental").isAudioMuted = true;
    5. }
    6.  
    I did it with my game. the static variable can be accessed throughout any scene, so if im in the main menu or in the first level, and i decide to mute all sounds, the static var isAudioMuted will become true on the AudioManager empty game object, which as a script called AudioCentral, with a bool called isAudioMuted which governs the audio listener on the main camera( all the main cameras in all scenes)
     
    Last edited: Jul 13, 2013
  49. technicat

    technicat

    Joined:
    Nov 22, 2006
    Posts:
    1,255
    That's a good tip. A lower level way to mute is just set AudioListener.pause (but then it's less clear to outside code that that mute was selected in the menu). I set AudioListener.pause in PauseGame and UnPauseGame, but it doesn't really need to be there, I just like the sound shut off when the pause menu is up. But it would be better to not do that if you want to hear the results when you change the sound volume or mute in the menu.
     
  50. eleynta

    eleynta

    Joined:
    Mar 20, 2013
    Posts:
    3
    I've been trying to make it so that the menu doesn't load on start (I have my own start level) but there doesn't seem to be an easy way to do it. I'm trying to put an UnPause after the initial Pause in Start(), but it either loads the sepia without the pause menu or it ignores OnLevelWasLoaded until the second time that I pause. Any thoughts?