What code do I need to make my game pause? How do I stop everything?
In the Editor, you can just click the pause button.
From gamecode, you can set Time.timeScale to 0. See the help entry. This should pause most of your game, assuming you don't rely on stuff like asking the actual system time. You can also set timeScale to anything between 0 and 1 (and even 1 and up), to modify the speed at which your gamesimulation progresses.
If you rely on the time to remain active during the pause you can also implement it a following way.
If an MonoBehaviour needs a pause action, like e.g. stopping the animation, implement an OnPauseGame() function. To handle resuming, implement an OnResumeGame() function.
When the game needs to pause, call the OnPauseGame function on all objects using something like this:
Object[] objects = FindObjectsOfType (typeof(GameObject));
foreach (GameObject go in objects) {
go.SendMessage ("OnPauseGame", SendMessageOptions.DontRequireReceiver);
}
And to resume call OnResumeGame on all objects.
A basic script with movement in the Update() could have something like this:
protected bool paused;
void OnPauseGame ()
{
paused = true;
}
void OnResumeGame ()
{
paused = false;
}
void Update ()
{
if (!paused) {
// do movement
}
}
A big benefit of doing it like this is that you can implement object specific pausing and resuming functionality, like storing and restoring information for objects that use physics.
If you set Time.timeScale to 0, yet you still want to do some processing (say, for animating pause menus), remember that Time.realtimeSinceStartup is not affected by Time.timeScale. You could effectively set up your own "deltaTime" in your animated menus by subtracting the previous recorded Time.realtimeSinceStartup from the current one.
If you're in the editor, you also have the option of calling Debug.Break to pause execution. This works just like pressing the pause button and is ignored at runtime, so you could use it to make debug-time "breakpoints".
Setting Time.timeScale to 0.0 works great as you still can have at the same time a Unity GUI on top that is still clickable and the rest of Unity freezes meanwhile.
You can also set it to a super tiny number like Time.timeScale = 0.0001f; so it wont really move but you still can use time related functions.
Alternatively, you can create a global variable in your game or level controller and toggle it between boolean states as pause is toggled. Then, make the execution of all pause-able code, wherever it might be, conditional, based on the state of that variable.
Note that you'll still need to pause all bodies in the physics simulation by setting their time step to 0 or similar technique.
This approach has the advantages of allowing you to pick and chose which code is effected by pausing, and it will work with code that isn't framerate independent.
Here's a sample pause menu script
I found alternative way - if you need to freese physics, but can’t stop timeScale(for example you need it for animation in menu or different ways). You can freeze some objects by disabling components and make all Rigidbodies non kinematics(Rigidbody doesn’t have enable property). Then you make Rigid non kinematic, it lost all current parameters - you need to save them.
Example for rigidbody:
bool isPause = false; //pause state of all game
//temporary arrays for rigidbody parameters
Rigidbody[] rigids;
Vector3[] velocity;
Vector3[] angularVelocity;
bool[] isKinematic;
public void SetPause(bool paused){
if (paused != isPaused) {
if (paused) { // save forces
rigids = gameObject.GetComponentsInChildren<Rigidbody>();//for all childs of this object
velocity = new Vector3[intent.rigids.Length];
angularVelocity = new Vector3[intent.rigids.Length];
isKinematic = new bool[intent.rigids.Length];
for(int i = 0; i < intent.rigids.Length; i ++) {
if (intent.rigids *!= null) {*
velocity = rigids*.velocity;*
angularVelocity = rigids*.angularVelocity;*
isKinematic = rigids*.isKinematic;*
_ rigids*.isKinematic = true;
}
}
} else { //restore forces*
* for(int i = 0; i < rigids.Length; i ++) {
if (rigids != null) {
rigids.isKinematic = isKinematic;
if (!isKinematic) { //restore velocity only for non kinematic objects*
rigids.velocity = velocity*;
rigids.angularVelocity = angularVelocity;
}
}
}
velocity = null;
angularVelocity = null;
isKinematic = null;
}
}
isPaused = paused;
}*_
Hello if you have not got the answer yet, please go through this post. I have made a Menu package in order to solve this problem. It might help you.
Setting timeScale to zero works for animations, but not audio, such as pausing an important speech or creating silence if the phone rings. I think that fix is to use Object.FindObjectsOfType(typeOf(AudioSource)) to get a list of every audio source in the scene, then do a foreach to make each one .Pause() when pausing, and .Play() when playing.
This is, of course, a very dull knife, as it will also start audio sources playing that may not have already been triggered. Thus, a complete solution will require testing each AudioSource for IsPlaying being true, if true pause it and add it to a PausedAudioSources list; when unpausing, go through all PausedAudioSources and set them to play, then empty that list. And of course, the very first thing you do is the timeScale to 0 as above, to stop something from waking up an audio source at just the right instant so the audio starts after all the already started audio sources have been captured, leaving a paused scene with on squeaky wheel.
A game.pause (such as we have when testing the game in Unity) would be even better.
I heavily modified the pause menu script found on the Unity wiki for my own game. I pasted below a link to the code I used (in JavaScript).
Go ahead and use it if you like.
Note: My game uses a First Person Controller. Part of the code turns on and off the MouseLook script on the First Person Controller and the Main Camera, which is a child object of the F.P.C., so that when you un-pause the game the character will still be looking in the same direction. Therefore, you'll probably have to adjust the PauseGame and UnPauseGame functions if you're not using a First Person Controller. In my game I attached the script itself to an empty game object.
If you go and download the FPS tutorials on unitys website, they have a part were it shows you how to start and stop the game via pause.
if(Input.GetKeyDown(“b”)){
Time.timeScale=0;
}
if(Input.GetKeyDown("escape")) { if(Time.timeScale > 0) { Time.timeScale = 0; } else Time.timeScale = 1; }
function OnGUI()
{
if(GUI.Button(Rect(Screen.width/2,Screen.height/2,Screen.width/8,Screen.height/8),"Play/Pause))
{
if(Time.timescale!=0)
{
Time.timescale=0;
}
else if(Time.timescale==0)
{
Time.timescale==1;
}
}
}
My answer is available for those who want to pause a Gameobject’s Rigidbody and resume it in order to have an animated pause menu or something not requiring to set Time.timeScale = 0
.
So, here is the way I found :
- Save your
rigidbody.velocity
(instance) - Pause the rigidbody using
rigidbody.Sleep()
orrigidbody.isKinematic = true
(both on your rigidbody instance) - Wait until the player wants to resume…
- Resume the rigidbody using
rigidbody.WakeUp()
orrigidbody.isKinematic = false
(both on your rigidbody instance) - Set up your
rigidbody.velocity
(instance) with the one you saved at the first step
The principe is to save your rigidbody’s datas before you “pause” it and restore datas on resuming.
Here is an exemple :
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
private Vector3 velocity;
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
// Pause the game when the player hit the Space key
velocity = rigidbody.velocity;
rigidbody.isKinematic = true;
} else if (Input.GetKeyUp(KeyCode.Space)) {
// Resume the game when the player release the Space key
rigidbody.isKinematic = false;
rigidbody.velocity = velocity;
}
}
}
public bool stopGame;
void Update ()
{
if (Input.GetKeyDown (KeyCode.Escape))
{
stopGame = true;
} else stopGame = false;
if (stopGame == true)
{
Time.timeScale = 0;
Debug.Log ("Game stopped");
}
if (stopGame == false)
{
Time.timeScale = 1;
Debug.Log ("Games !stopped");
}
}
You’ll often want to pause the game without affecting some GUI animations. To do that, you can set the Time.timeScale = 0 and set the animator’s update mode to Unscaled Time