Properly pausing a game

So this is one of things that have been annoying me from some time that I need to address. How to properly pause my game.

I have been able to implement pausing by setting Time.timeScale = 0.0 etc. however, doing that still allows the player access to the controls so then I have to have to create an a method in dependent classes to check if the game is in pauseState and it feels like there has to be a more elegant (or simpler) way to implement pausing the game. Moreover, I am using some physics and after un-pausing I get rather unpredictable behavior.

In other games I see on the iPhone, people somehow bring up a pop-up window which not only blocks the player from accessing the controls but also gives the player options to quit, etc. How is this done and what class or methods do I need to look into?

I am not asking for code or anything, just point me in the right direction.

Thank you for your time. :slight_smile:

I don’t think there is a simple plug ‘n’ play solution to your problem.

If you make your controls implement an interface you can easily control them all from a central class (e.g. ControlManager). On load each control could register with the ControlManager, when the game is paused the ControlManager sets all the controls to inactive. You could probably handle your touch events in this class too, invoking an action() method on the control when it is manipulated. A bit more coding to get it set up but once done it becomes easy to change controls and is reusable between projects.

On the physics side it’s a bit hard to solve without specific details.

JohnnyA,

Thank you for your response. I just wanted to make sure there wasn’t a more easier way but it looks like I will start working on using a ControlManager. I am still wondering about how to put a menu in front though, I guess it might just be OnGUI or something but I am still dying to know.

As far as the physics problems I mentioned earlier, an example would be the player shooting a gameObject with a rigid body (using gravity) and the object would react to the bullet collision and fly off. Currently, when I pause using Time.timeScale = 0 at the very moment the object is flying, then I unpause it again, the object flies off with a greater velocity as if it was somehow building up momentum while the game was paused.

Just create a global boolean like “gamepause” and set all your code you want to pause in a if function → if (gamepause == false){…}
After you startet your pause() function simply set your gamepause boolean = true and every function stops. after you leaving your pause screen set the gamepause boolean = false back again.

EDIT: OH! I didnet read your request completely. I dont know if my way works with physic objects :frowning:

Although I’m fairly confident I’d still wait for other answers just in case.

I have made a package. Just check out this link. May be it would help you somewhat (if not done yet).
MenuPackage

I’ve actually faced this problem two days ago, and the cleanest solution I found (timescale/Pause() not recommended) is to use coroutines in place of every Update() functions, and at the end put a custom yield return.
This custom return would be a Coroutine Unity type, which would be a single externalized coroutine (in a class component of its own, at best).
That coroutine would have 2 yield lines :

  • one yield return StartCoroutine(MyWaitForPauseCoroutine()), in which there would be a loop until your global pause variable is set to false
  • and one simple yield return new WaitForEndOfFrame();

That unique class would fire this above coroutine as soon as possible, and all of your other scripts would set a reference to its Coroutine as soon as they are created, so they can read its instance and place it at the end of every coroutine loops they would have.

You’ll also have to propagate a pause / resume state to every playing animations, but that’s not a big deal.

This method gives better control than Timescale for very little overhead imho.

edit : aaaaw :confused: seems like a coroutine can’t be shared by several yields :confused:
I’m searching for an alternative right now.

I would probably do the same thing as someone above posted. I probably just at the top of any function you didn’t want to run while “paused” just put in

if(paused)
return;

In most my scripts I have a reference to a empty game object that contains just my “general” scripts that just about all my other scripts can use.

I usually had a static variable for Pause and had controls to check if its false

Yep, I guess this " if (paused) " is good too :wink:

Okay, for those who are interested in coroutines, I found a way to make that Coroutine based Pause work :

In your class (or in any abstract/singleton you want), put these functions :

public Coroutine _sync(){
		return StartCoroutine(PauseRoutine());	
	}
	
public IEnumerator PauseRoutine(){
		while (_myPauseState) {
			yield return new WaitForFixedUpdate();	
		}
		yield return new WaitForEndOfFrame();	
	}

with _myPauseState being your global pause state.

then in any Coroutines, put this at the end (or at any place you want to check for a pause) :

yield return _sync();

This will work perfectly.

I’ll put this tip in script section too for better visibility.

Has anybody tried my package? I am asking because if “coroutines” or “if(paused)” are the best ways to implement this then i would try to change my scripts to give a better performance to games.

If you have physics objects, I would implement a static public enum pauseState { Playing, Pausing, Paused, Unpausing}.

All your objects would have a switch(myPauseState) { case StaticClass.pauseState.Playing, Pausing , Paused and Unpausing

Playing will execute your Update functions as normally intended.

Pausing will just jump to paused if it is a regular gameobject; if it is a rigidbody, it will save the velocity in a variable, and some other things you want to store; then it will set the rigidbody to kinematic and turn off use gravity if required; finally it will go to Paused.

Paused will run maybe your pop up menu, and something that may take it out of pause.

Unpausing will resetup back to playing, so, when you go to a playing state, your rigid bodies move the way they were supposed to be moving.

I usually create a manager class singleton that contains a list of objects that have registered to be notified about pause events. When the game pauses, there’s a public static variable that stores this info, so any script can check if the game is paused. Additionally, all registered classes are sent an event/delegate for both Pausing and Resuming, and they can do whatever they want with that information, which allows for very flexible handling of both events.

Like some others have said, for physics objects I just store their velocity, disabled physics on them, and restore/enable when resuming. I did this with Sticky and Munch Time, for instance.