A Proper Way To Pause A Game

Sorry i am a Beginner at Unity GUI and Time Scripting Stuff

I Want to Know How to Properly Pause the game in 3d

I dont want to use Time.timescale stuff Because most of my Game is in

FixedUpdate() And my Animated GUI Doesnt Work Nice with my Game

And If Your going to give scripts Id Prefer Unity Javascript More than C Sharp

C Sharp is OK If you cant provide Unity JS

I just want to know a technique

Or If you know Something else useful for this please inform me

My pause Script Is Something ike this

#pragma strict

public var pauseKey : String;

private var GamePaused : boolean;
function FixedUpdate(){
              //Dostuff
  if(Input.GetKey(pauseKey) ){
            if(GamePaused){  
            //Activate GUI
            //Pause Game with Time.timescale=0; stuff
            }
            else{
            //Play Game with time.timescale=1; stuff
            //Deactivate GUI 
            }
     }
}

Im not allowed to share the real
script

Plz help me quick

Other Details:

I use Unity 5 Personal edition

I use InstantGUI Asset for GUI
But I can also work with custom GUI

My Scene Has 3 cameras

  1. Game Screen

  2. radar

  3. Additional Information

My Scene has a terrain

My scene contains Custom Meshes From Blender

I Have More than 15 Javascript scripts

My scene contains Changing skyboxes Via scripts

My scene has over a 1000 characters controlled by one “Operator” script

I also have 2048*2048 tiling textures made in GIMP

I have Normal Maps Made with CrazyBump

I want to publish my Game to Non-Touch devices like PC,Mac,Linux,Xbox

I dont think you need any more details do you?

He, I know your question has been answered already, but here is some sample code :slight_smile:

this uses the panel object, it’s really easy this way

`
public class Pause : MonoBehaviour 
{
    [SerializeField] private GameObject pausePanel;
    void Start()
    {
        pausePanel.SetActive(false);
    }
    void Update()
    {
        if(Input.GetKeyDown (KeyCode.Escape)) 
        {
            if (!pausePanel.activeInHierarchy) 
            {
                PauseGame();
            }
            if (pausePanel.activeInHierarchy) 
            {
                 ContinueGame();   
            }
        } 
     }
    private void PauseGame()
    {
        Time.timeScale = 0;
        pausePanel.SetActive(true);
        //Disable scripts that still work while timescale is set to 0
    } 
    private void ContinueGame()
    {
        Time.timeScale = 1;
        pausePanel.SetActive(false);
        //enable the scripts again
    }
}
`

Good Luck

Usually whenever I pause the game, I freeze the player’s rigidbody and disable any input other than that required for the menu. I can’t give you any explicit ‘How to pause your game’ code, because each game is different. Just freeze everything that moves and stop the player from controlling the character.

CausticLasagne

I am using Time.timeScale to pause the game as well. I have too many objects doing some sort of animation or rigidbodies jumping around in order to freeze them all and reset them to their old velocity afterwards. I would have to check for pause state in every single script. :frowning:

Timescale works perfectly for this. My animated pause menu is just using Time.unscaledTime.

I think I understand

first,
i need to disable physics

next I need to Stop checking Input

//javascript
if(!paused){
   if(input.GetKey("up")){
  moveForward();
  }
}

then I need to stop my players reactions just in case

//javascript
function moveForward(){
  if(!paused){
    transform.Translate(Vector3.forward*SpeedMultiplier);
  }
}

finally I start the GUI

//javascript
if(paused){
//enable GUI
}

Anyways If you want to use these scripts then I license them CC-0!

I think @CausticLasagne is right. Setting time scale as 0 is not a good idea if you want to implement UI animation like cool down.

Add a button and attach a method call to it, in that method call make timeScale 0
and enable continue button.
attach a method call on continue button to hide continue button and make timeScale 1.

methods:

public void pauseGame(){
    Time.timeScale = 0;
    continueButton.setActive(true);
}
    
public void continueGame(){
    Time.timeScale = 1;
    continueButton.setActive(false);
}

@OsmiousH

I would use time.Timescale, I know that a few have said this is a bad idea and would rather pause each object through a bool, but I think it would be easier to set the animations to Time.fixedDeltaTime through coding. In my mind, it’s a matter of picking your poison.


Two things to consider when making any choice like this. How easy is it for you to do and how much processing power this would use.

My technique is to throw everything that I want disabled into a child of an object (named Game Manger for obvious reasons) then do a foreach loop on every child, setActive(false) on every one of them. Do a little camera taking a picture sequence, throw it into a render texture, and have that image held over the camera. Sorta giving it the illusion of actually pausing the game.


This is a very very easy windows only way to do this:


#if UNITY_STANDALONE_WIN using UnityEngine; using System.Runtime.InteropServices; using System;
  public class Minimize
   {
    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();

    public static void MinimizeGameWindow()
    {
        ShowWindow(GetActiveWindow(), 2);
    }
}
#endif

Then I call it in your monobehaviour script like this:

 #if UNITY_STANDALONE_WIN
      if (Input.GetKey(KeyCode.Escape))
           Minimize.MinimizeGameWindow();
  #endif

For Mac I think you can use this: NSWindow.Miniaturize(NSObject) Method (AppKit) | Microsoft Learn

P.S - For PC you also need to add a simulated middle mouse click (does nothing but unfocus the window, pausing the game):

using System;
using System.Runtime.InteropServices;

public class SimulatePCControl
{

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo);
    //Mouse actions

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern void keybd_event(uint bVk, uint bScan, uint dwFlags, uint dwExtraInfo);

    private const int MOUSEEVENTF_LEFTDOWN = 0x02;
    private const int MOUSEEVENTF_LEFTUP = 0x04;
    private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
    private const int MOUSEEVENTF_RIGHTUP = 0x10;
    private const int MOUSEEVENTF_MIDDLEDOWN = 0x20;
    private const int MOUSEEVENTF_MIDDLEUP = 0x40;

    [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);


    public enum ClickType { Left, Middle, Right }

    public static void Click(ClickType clickType, int _X, int _Y)
    {
        //Call the imported function with the cursor's current position
        uint X = (uint)_X;
        uint Y = (uint)_Y;

        switch (clickType)
        {
            case ClickType.Left:
                mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
                break;
            case ClickType.Middle:
                mouse_event(MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP, X, Y, 0, 0);
                break;
            case ClickType.Right:
                mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, X, Y, 0, 0);
                break;
        }
        
    }

}

This will simulate a middle click. Now you can pause your game like this after you minimize it:

        private void ProcessMinimizeApp()
        {
                if (HitPauseButton())
                {
                    MG_Minimize.MinimizeGameWindow();
                    SimulatePCControl.Click(SimulatePCControl.ClickType.Middle, 8000, 8000);
                }
        }

Simulating the middle mouse click off screen like that by putting in 8000,8000 seems to work for me.

Make sure to remember the ‘#if UNITY_STANDALONE_WIN’ for the windows parts, and then mac would work differently.

One line code:

if (Input.GetKeyDown(KeyCode.Space)) Time.timeScale = 1 - Time.timeScale;