- Home /
Creating a pause menu (problem using Time.timeScale)
I'm using the following code to call my pause menu, which is in a different script and is invoked when pauseVisible becomes true. It worked perfectly until I added the Time.timeScale lines to pause the game. Now when I open my pause menu, clicking buttons does nothing (obviously because timeScale is 0!). When I press 'P' to resume the game, it carries out whatever action I had taken, such as loading a certain level.
Since Time.timeScale seems to be the common method of pausing the game as far as I can see from the forums, has anyone else not been able to use their GUI buttons with this method? If it makes any difference, the print() statement I have to test the quit button still fires. Also, I tried putting all my code in the script that holds the gui stuff, but it doesn't work at all that way.
// open/close the pause menu
if( Input.GetKeyDown( KeyCode.P ) ){
if(pauseVisible){
pauseVisible = false;
Time.timeScale = 1.0;
GetComponent(MouseLook).enabled = true;
cam.GetComponent(MouseLook).enabled = true;
cam2.GetComponent(MouseLook).enabled = true;
} else {
pauseVisible = true;
Time.timeScale = 0.0;
GetComponent(MouseLook).enabled = false;
cam.GetComponent(MouseLook).enabled = false;
cam2.GetComponent(MouseLook).enabled = false;
}
}
Answer by Eric5h5 · Apr 16, 2010 at 10:48 PM
The time scale being 0 doesn't have any effect on GUI buttons, so the problem must be elsewhere. Incidentally, for toggling things, you can use code like:
if (Input.GetKeyDown(KeyCode.P) ) {
pauseVisible = !pauseVisible;
Time.timeScale = 1.0-Time.timeScale;
GetComponent(MouseLook).enabled = !GetComponent(MouseLook).enabled;
cam.GetComponent(MouseLook).enabled = !cam.GetComponent(MouseLook).enabled;
cam2.GetComponent(MouseLook).enabled = !cam2.GetComponent(MouseLook).enabled;
}
Thanks Eric, I'll have a look through my code. Yeah, thanks, I know you can, I just like to see plain English=S
Answer by straydogstrut · Apr 17, 2010 at 01:04 AM
After scratching my head for ages finding nothing wrong i've discovered that I only reset Time.timeScale to 1.0 when pressing the 'P' key, but not when choosing an option in the menu. It wasn't until I commented out a yield statement that I discovered that the level was being loaded, but was not getting any further than my fade in script since time was at a stand still.
I've added lines to set Time.timeScale to 1.0 after pressing the buttons and it works perfectly now. My full, revised code is:
var click : AudioClip; var menuSkin : GUISkin; var areaWidth : float; var areaHeight : float; var theTexture : Texture2D;
static var pauseVisible : boolean; private var player : GameObject; private var cam : GameObject; private var cam2 : GameObject;
function Start(){
// initially hide the pause menu
pauseVisible = false;
player = GameObject.Find("First Person Controller");
cam = GameObject.Find("Main Camera");
cam2 = GameObject.Find("Secondary Camera");
}
function Update(){
if( Input.GetKeyUp( KeyCode.P ) ){
if(Time.timeScale == 1.0){
Time.timeScale = 0;
pauseVisible = true;
player.GetComponent(MouseLook).enabled = false;
cam.GetComponent(MouseLook).enabled = false;
cam2.GetComponent(MouseLook).enabled = false;
} else {
Time.timeScale = 1.0;
pauseVisible = false;
player.GetComponent(MouseLook).enabled = true;
cam.GetComponent(MouseLook).enabled = true;
cam2.GetComponent(MouseLook).enabled = true;
}
}
}
function OnGUI () {
if(pauseVisible){
GUI.skin = menuSkin;
GUI.color = Color.white;
GUI.color.a = 0.5;
GUI.DrawTexture(Rect(0, 0, Screen.width, Screen.height), theTexture);
var ScreenX = ((Screen.width * 0.5) - (areaWidth * 0.5));
var ScreenY = ((Screen.height * 0.5) - (areaHeight * 0.5));
GUILayout.BeginArea(Rect(ScreenX, ScreenY, areaWidth, areaHeight));
if(GUILayout.Button("Restart Level")){
OpenLevel("level01");
Time.timeScale = 1.0;
}
if(GUILayout.Button("Quit To Menu")){
OpenLevel("menu");
Time.timeScale = 1.0;
}
GUILayout.EndArea();
}
}
function OpenLevel(level : String){ audio.PlayOneShot(click); yield WaitForSeconds(0.35); Application.LoadLevel(level);
}
@script RequireComponent (AudioSource)
0
I have tried this code, however it keeps saying unknown iditfier for $$anonymous$$ouseLook any ideas?
$$anonymous$$ouseLook is the script on the first person controller found in Standard Assets>Prefabs. In my case i've renamed my fps controller to 'player'. In your project, doublecheck which object it's on and what it's called. Also note that there are two $$anonymous$$ouseLook scripts (the other one is on the camera). I'm using two cameras in my game, hence the third line disabling cam2. If you can't get it working, maybe start a new question with some code and i'll have a look.
Answer by Djcmoon · May 31, 2010 at 09:48 AM
I need help with a slightly different code:
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class MenuController : MonoBehaviour {
static int difficulty = 1;
public GUISkin skin;
private List animationComponents;
private List audioSourceComponents;
private float menuOn = 0;
private float lastTime = 0;
int[] playerHitDamage = new int[5] { 3, 4, 6, 10, 20 };
int[] playerHeal = new int[5] { 5, 4, 3, 2, 0 };
int[] enemyHitDamage = new int[5] { 10, 5, 2, 2, 2 };
int[] enemyHeal = new int[5] { 0, 0, 0, 0, 0 };
// Use this for initialization
IEnumerator Start () {
UpdateDifficulty();
AudioListener.volume = 0;
yield return 0;
AudioListener.volume = 1;
}
// Update is called once per frame
void Update () {
// Don't pause in first frame - allow scripts to settle in first
if (Time.timeSinceLevelLoad == 0)
return;
float realDeltaTime = (Time.realtimeSinceStartup - lastTime);
lastTime = Time.realtimeSinceStartup;
menuOn = Mathf.Clamp01(menuOn + (Time.timeScale == 0 ? 1 : -1) * realDeltaTime * 5);
if (!Screen.lockCursor && Time.timeScale != 0) {
StartCoroutine(Pause(true));
}
}
void OnGUI () {
if (menuOn == 0)
return;
GUI.skin = skin;
// PLAY button
Rect rect = new Rect(0, 0, 150, 75);
rect.x = (Screen.width - rect.width ) / 2 + (1 - menuOn) * Screen.width;
rect.y = (Screen.height - rect.height) / 2;
if (GUI.Button(rect, "PLAY")) {
StartCoroutine(Pause(false));
}
// Difficulty buttons
rect = new Rect(rect.x - 200, rect.y + 150, rect.width + 400, 40);
string[] difficulties = new string[] {"NO FAIL", "EASY", "MEDIUM", "HARD", "INSANE"};
int newDifficulty = GUI.SelectionGrid(rect, difficulty, difficulties, difficulties.Length);
if (newDifficulty != difficulty) {
difficulty = newDifficulty;
UpdateDifficulty();
}
}
IEnumerator Pause (bool pause) {
// Pause/unpause time
Time.timeScale = (pause ? 0 : 1);
// Unlock/Lock cursor
Screen.lockCursor = !pause;
if (pause == true) {
Object[] objects = FindObjectsOfType(typeof(Animation));
animationComponents = new List();
foreach (Object obj in objects) {
Animation anim = (Animation)obj;
if (anim != null && anim.enabled) {
animationComponents.Add(anim);
anim.enabled = false;
}
}
objects = FindObjectsOfType(typeof(AudioSource));
audioSourceComponents = new List();
foreach (Object obj in objects) {
AudioSource source = (AudioSource)obj;
if (source != null && source.enabled /*&& source.isPlaying*/) {
audioSourceComponents.Add(source);
source.Pause();
}
}
}
else {
// If unpausing, wait one frame before we enable animation component.
// Procedural adjustments are one frame delayed because first frame
// after being paused has deltaTime of 0.
yield return 0;
foreach (Animation anim in animationComponents)
anim.enabled = true;
foreach (AudioSource source in audioSourceComponents)
source.Play();
animationComponents = null;
}
}
void UpdateDifficulty () {
Object[] objects = FindObjectsOfType(typeof(HealthController));
foreach (Object obj in objects) {
HealthController health = (HealthController)obj;
if (health.gameObject.tag == "Player") {
health.healingSpeed = playerHeal[difficulty];
health.hitDamage = playerHitDamage[difficulty];
}
else {
health.healingSpeed = enemyHeal[difficulty];
health.hitDamage = enemyHitDamage[difficulty];
}
}
}
}
I didn't make this code and I want to get rid of it and use the code posted above.
I would be fine even if I could just get rid of the difficulty buttons and add a qiut to menu and a restart level button but for some reason, if I get rid of the code or even just the difficulty buttons, the game won't work properly.
Any help is appreciated
Thank you in advance (ps: this is for a 3rd person game and I only want one set difficulty witch is why I don't want the buttons.)
Don't post your question as an answer to another question, this isn't a forum (Actually, in a forum you wouldn't even do that, either). Start a new question.
Your answer
Follow this Question
Related Questions
Set Timescale to 0 for game, except for pause menu 2 Answers
Time.timeScale=0 Problem Help please 1 Answer
Pausing an Invoke for a time 2 Answers
2D main menu as a different scene - pausing and resuming 0 Answers
How to pause and unpause my game - Input.GetAxis doesn't work when Time.timeScale is 0 3 Answers