PauseMenu

From Unify Community Wiki
Jump to: navigation, search

Contents

Overview

A pause menu with multiple screens for credits and options (audio and visual, system info, stats). Doubles as the start menu and is invoked when ESC is hit. This was used for all my Unity web and widget minigames on Fugu Games. This was not originally run on iOS - if you get the type of errors that you also get from adding #pragma strict then add type declarations where necessary - referring to the C# version (added by another contributor) may help. Also, the C# may run better on iOS (and Android). A sample project with the Javascript version is on the Asset Store (currently, $2) and another version is on github.

Setup

  • Attach this to the main camera
  • If a SepiaToneFilter is attached to the main camera, it will be activated on pause.
  • Sepia filter (and image effects in general) are a Pro-only feature. If you have Unity Indie, comment out the sepiaFilter assignment.
  • You need to assign a material to the script's Mat slot for the FPS graph to display - I usually assign an all-white VertexLit material.

How It Works

Javascript Version

var skin:GUISkin;
 
private var gldepth = -0.5;
private var startTime = 0.1;
 
var mat:Material;
 
private var tris = 0;
private var verts = 0;
private var savedTimeScale:float;
private var pauseFilter;
 
private var showfps:boolean;
private var showtris:boolean;
private var showvtx:boolean;
private var showfpsgraph:boolean;
 
var lowFPSColor = Color.red;
var highFPSColor = Color.green;
 
var lowFPS = 30;
var highFPS = 50;
 
var start:GameObject;
 
var url = "unity.html";
 
var statColor:Color = Color.yellow;
 
var credits:String[]=[
	"A Fugu Games Production",
	"Programming by Phil Chu",
	"Fugu logo by Shane Nakamura Designs",
	"Copyright (c) 2007-2008 Technicat, LLC"] ;
var crediticons:Texture[];
 
enum Page {
	None,Main,Options,Credits
}
 
private var currentPage:Page;
 
private var fpsarray:int[];
private var fps:float;
 
function Start() {
	fpsarray = new int[Screen.width];
	Time.timeScale = 1.0;
	pauseFilter = Camera.main.GetComponent(SepiaToneEffect);
	PauseGame();
}
 
function OnPostRender() {
	if (showfpsgraph && mat != null) {
		GL.PushMatrix ();
		GL.LoadPixelMatrix();
		for (var i = 0; i < mat.passCount; ++i)
		{
			mat.SetPass(i);
			GL.Begin( GL.LINES );
			for (var x=0; x<fpsarray.length; ++x) {
				GL.Vertex3(x,fpsarray[x],gldepth);
			}
		GL.End();
		}
		GL.PopMatrix();
		ScrollFPS();
	}
}
 
function ScrollFPS() {
	for (var x=1; x<fpsarray.length; ++x) {
		fpsarray[x-1]=fpsarray[x];
	}
	if (fps < 1000) {
		fpsarray[fpsarray.length-1]=fps;
	}
}
 
static function IsDashboard() {
	return Application.platform == RuntimePlatform.OSXDashboardPlayer;
}
 
static function IsBrowser() {
	return (Application.platform == RuntimePlatform.WindowsWebPlayer ||
		Application.platform == RuntimePlatform.OSXWebPlayer);
}
 
function LateUpdate () {
	if (showfps || showfpsgraph) {
		FPSUpdate();
	}
	if (Input.GetKeyDown("escape")) {
		switch (currentPage) {
			case Page.None: PauseGame(); break;
			case Page.Main: if (!IsBeginning()) UnPauseGame(); break;
			default: currentPage = Page.Main;
		}
	}
}
 
function OnGUI () {
	if (skin != null) {
		GUI.skin = skin;
	}
	ShowStatNums();
	ShowLegal();
	if (IsGamePaused()) {
		GUI.color = statColor;
		switch (currentPage) {
			case Page.Main: PauseMenu(); break;
			case Page.Options: ShowToolbar(); break;
			case Page.Credits: ShowCredits(); break;
		}
	}	
}
 
function ShowLegal() {
	if (!IsLegal()) {
		GUI.Label(Rect(Screen.width-100,Screen.height-20,90,20),
		"fugugames.com");
	}
}
 
function IsLegal() {
	return !IsBrowser() || 
	Application.absoluteURL.StartsWith("http://www.fugugames.com/") ||
	Application.absoluteURL.StartsWith("http://fugugames.com/");
}
 
private var toolbarInt:int=0;
private var toolbarStrings: String[]= ["Audio","Graphics","Stats","System"];
 
function ShowToolbar() {
	BeginPage(300,300);
	toolbarInt = GUILayout.Toolbar (toolbarInt, toolbarStrings);
	switch (toolbarInt) {
		case 0: VolumeControl(); break;
		case 3: ShowDevice(); break;
		case 1: Qualities(); QualityControl(); break;
		case 2: StatControl(); break;
	}
	EndPage();
}
 
function ShowCredits() {
	BeginPage(300,300);
	for (var credit in credits) {
		GUILayout.Label(credit);
	}
	for (var credit in crediticons) {
		GUILayout.Label(credit);
	}
	EndPage();
}
 
function ShowBackButton() {
	if (GUI.Button(Rect(20,Screen.height-50,50,20),"Back")) {
		currentPage = Page.Main;
	}
}
 
 
function ShowDevice() {
	GUILayout.Label ("Unity player version "+Application.unityVersion);
	GUILayout.Label("Graphics: "+SystemInfo.graphicsDeviceName+" "+
	SystemInfo.graphicsMemorySize+"MB\n"+
	SystemInfo.graphicsDeviceVersion+"\n"+
	SystemInfo.graphicsDeviceVendor);
	GUILayout.Label("Shadows: "+SystemInfo.supportsShadows);
	GUILayout.Label("Image Effects: "+SystemInfo.supportsImageEffects);
	GUILayout.Label("Render Textures: "+SystemInfo.supportsRenderTextures);
}
 
function Qualities() {
        GUILayout.Label(QualitySettings.names[QualitySettings.GetQualityLevel()]);
}
 
function QualityControl() {
	GUILayout.BeginHorizontal();
	if (GUILayout.Button("Decrease")) {
		QualitySettings.DecreaseLevel();
	}
	if (GUILayout.Button("Increase")) {
		QualitySettings.IncreaseLevel();
	}
	GUILayout.EndHorizontal();
}
 
function VolumeControl() {
	GUILayout.Label("Volume");
	AudioListener.volume = GUILayout.HorizontalSlider(AudioListener.volume,0.0,1.0);
}
 
function StatControl() {
	GUILayout.BeginHorizontal();
	showfps = GUILayout.Toggle(showfps,"FPS");
	showtris = GUILayout.Toggle(showtris,"Triangles");
	showvtx = GUILayout.Toggle(showvtx,"Vertices");
	showfpsgraph = GUILayout.Toggle(showfpsgraph,"FPS Graph");
	GUILayout.EndHorizontal();
}
 
function FPSUpdate() {
	var delta = Time.smoothDeltaTime;
		if (!IsGamePaused() && delta !=0.0) {
			fps = 1 / delta;
		}
}
 
function ShowStatNums() {
	GUILayout.BeginArea(Rect(Screen.width-100,10,100,200));
	if (showfps) {
		var fpsString= fps.ToString ("#,##0 fps");
		GUI.color = Color.Lerp(lowFPSColor, highFPSColor,(fps-lowFPS)/(highFPS-lowFPS));
		GUILayout.Label (fpsString);
	}
	if (showtris || showvtx) {
		GetObjectStats();
		GUI.color = statColor;
	}
	if (showtris) {
		GUILayout.Label (tris+"tri");
	}
	if (showvtx) {
		GUILayout.Label (verts+"vtx");
	}
	GUILayout.EndArea();
}
 
function BeginPage(width,height) {
	GUILayout.BeginArea(Rect((Screen.width-width)/2,(Screen.height-height)/2,width,height));
}
 
function EndPage() {
	GUILayout.EndArea();
	if (currentPage != Page.Main) {
		ShowBackButton();
	}
}
 
function IsBeginning() {
	return Time.time < startTime;
}
 
 
function PauseMenu() {
	BeginPage(200,200);
	if (GUILayout.Button (IsBeginning() ? "Play" : "Continue")) {
		UnPauseGame();
 
	}
	if (GUILayout.Button ("Options")) {
		currentPage = Page.Options;
	}
	if (GUILayout.Button ("Credits")) {
		currentPage = Page.Credits;
	}
	if (IsBrowser() && !IsBeginning() && GUILayout.Button ("Restart")) {
		Application.OpenURL(url);
	}
	EndPage();
}
 
function GetObjectStats() {
	verts = 0;
	tris = 0;
	var ob = FindObjectsOfType(GameObject);
	for (var obj in ob) {
		GetObjectStats(obj);
	}
}
 
function GetObjectStats(object) {
	var filters : Component[];
	filters = object.GetComponentsInChildren(MeshFilter);
	for( var f : MeshFilter in filters )
	{
    	tris += f.sharedMesh.triangles.Length/3;
  		verts += f.sharedMesh.vertexCount;
	}
}
 
function PauseGame() {
	savedTimeScale = Time.timeScale;
	Time.timeScale = 0;
	AudioListener.pause = true;
	if (pauseFilter) pauseFilter.enabled = true;
	currentPage = Page.Main;
}
 
function UnPauseGame() {
	Time.timeScale = savedTimeScale;
	AudioListener.pause = false;
	if (pauseFilter) pauseFilter.enabled = false;
	currentPage = Page.None;
	if (IsBeginning() && start != null) {
		start.active = true;
	}
}
 
function IsGamePaused() {
	return Time.timeScale==0;
}
 
function OnApplicationPause(pause:boolean) {
	if (IsGamePaused()) {
		AudioListener.pause = true;
	}
}

C# version

using UnityEngine;
using System.Collections;
 
public class PauseMenu : MonoBehaviour
{
 
	public GUISkin skin;
 
	private float gldepth = -0.5f;
	private float startTime = 0.1f;
 
	public Material mat;
 
	private long tris = 0;
	private long verts = 0;
	private float savedTimeScale;
	private SepiaToneEffect pauseFilter;
 
	private bool showfps;
	private bool showtris;
	private bool showvtx;
	private bool showfpsgraph;
 
	public Color lowFPSColor = Color.red;
	public Color highFPSColor = Color.green;
 
	public int lowFPS = 30;
	public int highFPS = 50;
 
	public GameObject start;
 
	public string url = "unity.html";
 
	public Color statColor = Color.yellow;
 
	public string[] credits= {
	    "A Fugu Games Production",
	    "Programming by Phil Chu",
	    "Fugu logo by Shane Nakamura Designs",
	    "Copyright (c) 2007-2008 Technicat, LLC"} ;
	public Texture[] crediticons;
 
	public enum Page {
	    None,Main,Options,Credits
	}
 
	private Page currentPage;
 
	private float[] fpsarray;
	private float fps;
 
	private int toolbarInt = 0;
	private string[]  toolbarstrings =  {"Audio","Graphics","Stats","System"};
 
 
	void Start() {
	    fpsarray = new float[Screen.width];
	    Time.timeScale = 1;
	    pauseFilter = Camera.main.GetComponent<SepiaToneEffect>();
	    PauseGame();
	}
 
	void OnPostRender() {
	    if (showfpsgraph && mat != null) {
	        GL.PushMatrix ();
	        GL.LoadPixelMatrix();
	        for (var i = 0; i < mat.passCount; ++i)
	        {
	            mat.SetPass(i);
	            GL.Begin( GL.LINES );
	            for (int x=0; x < fpsarray.Length; ++x) {
	                GL.Vertex3(x, fpsarray[x], gldepth);
	            }
	        GL.End();
	        }
	        GL.PopMatrix();
	        ScrollFPS();
	    }
	}
 
	void ScrollFPS() {
	    for (int x = 1; x < fpsarray.Length; ++x) {
	        fpsarray[x-1]=fpsarray[x];
	    }
	    if (fps < 1000) {
	        fpsarray[fpsarray.Length - 1]=fps;
	    }
	}
 
	static bool IsDashboard() {
	    return Application.platform == RuntimePlatform.OSXDashboardPlayer;
	}
 
	static bool IsBrowser() {
	    return (Application.platform == RuntimePlatform.WindowsWebPlayer ||
	        Application.platform == RuntimePlatform.OSXWebPlayer);
	}
 
	void LateUpdate () {
	    if (showfps || showfpsgraph) {
	        FPSUpdate();
	    }
 
		if (Input.GetKeyDown("escape")) 
		{
	        switch (currentPage) 
			{
	            case Page.None: 
					PauseGame(); 
					break;
 
				case Page.Main: 
					if (!IsBeginning()) 
						UnPauseGame(); 
					break;
 
				default: 
					currentPage = Page.Main;
					break;
	        }
	    }
	}
 
	void OnGUI () {
	    if (skin != null) {
	        GUI.skin = skin;
	    }
	    ShowStatNums();
	    ShowLegal();
	    if (IsGamePaused()) {
	        GUI.color = statColor;
	        switch (currentPage) {
	            case Page.Main: MainPauseMenu(); break;
	            case Page.Options: ShowToolbar(); break;
	            case Page.Credits: ShowCredits(); break;
	        }
	    }   
	}
 
	void ShowLegal() {
	    if (!IsLegal()) {
	        GUI.Label(new Rect(Screen.width-100,Screen.height-20,90,20),
	        "jdonavan.com");
	    }
	}
 
	bool IsLegal() {
	    return !IsBrowser() || 
	    Application.absoluteURL.StartsWith("http://www.jdonavan.com/") ||
	    Application.absoluteURL.StartsWith("http://jdonavan.com/");
 
	}
 
	void ShowToolbar() {
	    BeginPage(300,300);
	    toolbarInt = GUILayout.Toolbar (toolbarInt, toolbarstrings);
	    switch (toolbarInt) {
	        case 0: VolumeControl(); break;
	        case 3: ShowDevice(); break;
	        case 1: Qualities(); QualityControl(); break;
	        case 2: StatControl(); break;
	    }
	    EndPage();
	}
 
	void ShowCredits() {
	    BeginPage(300,300);
	    foreach(string credit in credits) {
	        GUILayout.Label(credit);
	    }
	    foreach( Texture credit in crediticons) {
	        GUILayout.Label(credit);
	    }
	    EndPage();
	}
 
	void ShowBackButton() {
	    if (GUI.Button(new Rect(20, Screen.height - 50, 50, 20),"Back")) {
	        currentPage = Page.Main;
	    }
	}
 
	void ShowDevice() {
	    GUILayout.Label("Unity player version "+Application.unityVersion);
	    GUILayout.Label("Graphics: "+SystemInfo.graphicsDeviceName+" "+
	    SystemInfo.graphicsMemorySize+"MB\n"+
	    SystemInfo.graphicsDeviceVersion+"\n"+
	    SystemInfo.graphicsDeviceVendor);
	    GUILayout.Label("Shadows: "+SystemInfo.supportsShadows);
	    GUILayout.Label("Image Effects: "+SystemInfo.supportsImageEffects);
	    GUILayout.Label("Render Textures: "+SystemInfo.supportsRenderTextures);
	}
 
	void 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;
	    }
	}
 
	void QualityControl() {
	    GUILayout.BeginHorizontal();
	    if (GUILayout.Button("Decrease")) {
	        QualitySettings.DecreaseLevel();
	    }
	    if (GUILayout.Button("Increase")) {
	        QualitySettings.IncreaseLevel();
	    }
	    GUILayout.EndHorizontal();
	}
 
	void VolumeControl() {
	    GUILayout.Label("Volume");
	    AudioListener.volume = GUILayout.HorizontalSlider(AudioListener.volume, 0, 1);
	}
 
	void StatControl() {
	    GUILayout.BeginHorizontal();
	    showfps = GUILayout.Toggle(showfps,"FPS");
	    showtris = GUILayout.Toggle(showtris,"Triangles");
	    showvtx = GUILayout.Toggle(showvtx,"Vertices");
	    showfpsgraph = GUILayout.Toggle(showfpsgraph,"FPS Graph");
	    GUILayout.EndHorizontal();
	}
 
	void FPSUpdate() {
	    float delta = Time.smoothDeltaTime;
	        if (!IsGamePaused() && delta !=0.0) {
	            fps = 1 / delta;
	        }
	}
 
	void ShowStatNums() {
	    GUILayout.BeginArea( new Rect(Screen.width - 100, 10, 100, 200));
	    if (showfps) {
	        string fpsstring= fps.ToString ("#,##0 fps");
	        GUI.color = Color.Lerp(lowFPSColor, highFPSColor,(fps-lowFPS)/(highFPS-lowFPS));
	        GUILayout.Label (fpsstring);
	    }
	    if (showtris || showvtx) {
	        GetObjectStats();
	        GUI.color = statColor;
	    }
	    if (showtris) {
	        GUILayout.Label (tris+"tri");
	    }
	    if (showvtx) {
	        GUILayout.Label (verts+"vtx");
	    }
	    GUILayout.EndArea();
	}
 
	void BeginPage(int width, int height) {
	    GUILayout.BeginArea( new Rect((Screen.width - width) / 2, (Screen.height - height) / 2, width, height));
	}
 
	void EndPage() {
	    GUILayout.EndArea();
	    if (currentPage != Page.Main) {
	        ShowBackButton();
	    }
	}
 
	bool IsBeginning() {
	    return (Time.time < startTime);
	}
 
 
	void MainPauseMenu() {
	    BeginPage(200,200);
	    if (GUILayout.Button (IsBeginning() ? "Play" : "Continue")) {
	        UnPauseGame();
 
	    }
	    if (GUILayout.Button ("Options")) {
	        currentPage = Page.Options;
	    }
	    if (GUILayout.Button ("Credits")) {
	        currentPage = Page.Credits;
	    }
	    if (IsBrowser() && !IsBeginning() && GUILayout.Button ("Restart")) {
	        Application.OpenURL(url);
	    }
	    EndPage();
	}
 
	void GetObjectStats() {
	    verts = 0;
	    tris = 0;
	    GameObject[] ob = FindObjectsOfType(typeof(GameObject)) as GameObject[];
	    foreach (GameObject obj in ob) {
	        GetObjectStats(obj);
	    }
	}
 
	void GetObjectStats(GameObject obj) {
	   	Component[] filters;
	    filters = obj.GetComponentsInChildren<MeshFilter>();
	    foreach( MeshFilter f  in filters )
	    {
	        tris += f.sharedMesh.triangles.Length/3;
	      	verts += f.sharedMesh.vertexCount;
	    }
	}
 
	void PauseGame() {
	    savedTimeScale = Time.timeScale;
	    Time.timeScale = 0;
	    AudioListener.pause = true;
	    if (pauseFilter) 
			pauseFilter.enabled = true;
	    currentPage = Page.Main;
	}
 
	void UnPauseGame() {
	    Time.timeScale = savedTimeScale;
	    AudioListener.pause = false;
	    if (pauseFilter) 
			pauseFilter.enabled = false;
 
		currentPage = Page.None;
 
		if (IsBeginning() && start != null) {
	        start.active = true;
	    }
	}
 
	bool IsGamePaused() {
	    return (Time.timeScale == 0);
	}
 
	void OnApplicationPause(bool pause) {
	    if (IsGamePaused()) {
	        AudioListener.pause = true;
	    }
	}
}
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox