Hey I am trying to make a pause menu in my game. When escape is pressed pause game go to menu, but now I want to be able to press back in menu and resume my game. So far I can only pause game and cant press back. Also if i press Play in menu it starts at my tutorial scene and not the current scene. Is there a smart way to do this? Without resetting my game.
`using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MenuScript : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
if (Time.timeScale == 0)
{
Time.timeScale = 1;
}
else
{
Time.timeScale = 0;
}
SceneManager.LoadScene("Menu");
}
}
}`
I get that this isn't straightforward problem since you seem new to Unity.
You got the idea correctly, changing the time scale will freeze all agents on the scene. HOWEVER, if you load a new scene you'll need to reload the game scene - losing any data you had (and that is not what you want). My advice is creating an overlay element (UI) on the game scene and just show/hide it. There are multiple tutorials online use this as an starting point. Let me know if you require more help.
code sample
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
if (Time.timeScale == 0)
{
Time.timeScale = 1;
pauseMenu.gameObject.setActive(true);
}
else
{
Time.timeScale = 0;
pauseMenu.gameObject.setActive(false);
}
}
}
You will need a reference to the pauseMenu game object attached on this script using the Unity editor.
Depending on what you need, this would work as well.
private bool _isPaused;
private void Update(){
if (Input.GetKeyUp(KeyCode.Escape))
{
_isPaused = !_isPaused;
if (_isPaused)
{
//Do Pause Logic here
}
else
{
//Do Unpause Logic Here
}
}
}
Related
I'm stuck on the last test for my app before submission to the Oculus store. I've tried all sorts with no avail. I need to do is pass the frames when not visible test.
Effectively, the app needs to go into pause mode when the user clicks the menu button on the oculus touch controller.
I need to stop all frames submitting from Unity. For example, things I've tried, turn off cameras, audio, ovrplayercontroller etc but frames being submitted when the menu button is pressed on the rift so it would appear to freeze the application.
I've tried disabling cameras in a foreach loop, disabling the player gameobject, ovr controllers all sorts.
I have a gameobject with a script attached to try and detect when the test will fire based on the HMD losing tracking.
Here's where I'm currently at (gone back to the basics again), any help would be greatly appreciated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HMDCheck : MonoBehaviour
{
public GameObject OVRCameraRig;
private void Update()
{
if (!OVRManager.isHmdPresent)
{
OVRCameraRig.SetActive(false);
Time.timeScale = 0f;
}
else
{
OVRCameraRig.SetActive(true);
Time.timeScale = 1f;
}
}
}
Additionally their docs say the test performs this action:
TestSubmitFramesWhenNotVisible
Tests if your app stops submitting frames when the Universal Menu is open.
Note :
My most recent command line response for the test is the following output :
Starting TestSubmitFramesWhenNotVisible
Waiting for the application to run for 5 seconds before testing begins...
Starting test...
Requesting the void...
Number of texture swap chains committed when visible 68
Number of texture swap chains committed when not visible 4
ERROR: Committed a texture swap chain (called ovr_CommitTextureSwapChain) when application not visible
Please refer to VRC Guidelines:
https://developer.oculus.com/distribute/latest/concepts/vrc-pc-input-1/
Cleaning up...
Test FAILED
To get around it, I created a script with public gameobjects. I then dragged my player into the slots inside Unity but left the camera on the scene alone. Here's a screenshot and the code. I initially added the camera to turn off frames sending but Oculus rejected it as it froze in the background upon pressing the menu button.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HMDCheck : MonoBehaviour
{
public GameObject target, scripts, LocalAvatar;
private void Update()
{
if (!OVRManager.hasVrFocus || !OVRManager.isHmdPresent || !OVRManager.hasInputFocus)
{
//target.SetActive(false);
scripts.SetActive(false);
LocalAvatar.SetActive(false);
Time.timeScale = 0f;
AudioListener.pause = true;
}
else
{
//target.SetActive(true);
scripts.SetActive(true);
LocalAvatar.SetActive(true);
Time.timeScale = 1f;
AudioListener.pause = false;
}
}
}
I have almost the same code, but this detects the Universal Menu correctly and does freeze the output, but it still won't pass the test. I think it may pass if you disable splash screens, but can't know since I have the free version of Unity.
Edit: I saw your answer Diego, but cannot comment. Did your action resolve your original question? And what license do you have for Unity?
Camera cam;
bool bPause = false;
void Update()
{
//install 'Oculus Integration' for this to work
bool bPauseNow = !(OVRManager.hasInputFocus && OVRManager.hasVrFocus);
//pause state change
if (Camera.main != null) cam = Camera.main;
if (bPause != bPauseNow)
{
bPause = bPauseNow;
if (bPauseNow)
{
Time.timeScale = 0.0f; //stops FixedUpdate
//Update keeps running, but
// rendering must also be paused to pass vrc
cam.enabled = false;
}
else
{
Time.timeScale = 1.0f;
//
cam.enabled = true;
}
}
//...
}
I am using the "Oculus XR Plugin", and got this issue,
but I found that the results of the "VRC Validator" are not so accurate,
then I submitted the App for review and passed the test.
I created an animator called "m4a4animator". Inside it, the main function is called "idle" (nothing), and other 2 states: "shoot" (mouse0) and "reload" (R). These 2 animation states are transitioned to "idle". Now, everything is working... but the only problem I have is this: if I am in the middle of reloading and and press mouse0 (shoot), the animation running state immediately changes to shoot... but I want to block that.
Now, the question: How can I stop CERTAIN animation changes while an animation is running?
Here is my animator
And here is my script:
using UnityEngine;
using System.Collections;
public class m4a4 : MonoBehaviour {
public Animator m4a4animator;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.R)) {
m4a4animator.Play("reload");
}
if (Input.GetMouseButton(0)) {
m4a4animator.Play("shoot");
}
}
}
For the legacy Animation system, Animation.IsPlaying("TheAnimatonClipName) is used to check if the animation clip is playing.
For the new Mechanim Animator system, you have to check if both anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) and anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f) are true. If they are then animation name is currently playing.
This can be simplified like the function like the Animation.IsPlaying function above.
bool isPlaying(Animator anim, string stateName)
{
if (anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) &&
anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f)
return true;
else
return false;
}
Now, everything is working... but the only problem I have is this: if
I am in the middle of reloading and and press mouse0 (shoot), the
animation running state immediately changes to shoot... but I want to
block that.
When the shoot button is pressed, check if the "reload" animation is playing. If it is, don't shoot.
public Animator m4a4animator;
int animLayer = 0;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
m4a4animator.Play("reload");
}
//Make sure we're not reloading before playing "shoot" animation
if (Input.GetMouseButton(0) && !isPlaying(m4a4animator, "reload"))
{
m4a4animator.Play("shoot");
}
}
bool isPlaying(Animator anim, string stateName)
{
if (anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) &&
anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f)
return true;
else
return false;
}
If you need to wait for the "reload" animation to finish playing before playing the "shoot" animation then use a coroutine. This post described how to do so.
There are other threads about that: https://answers.unity.com/questions/362629/how-can-i-check-if-an-animation-is-being-played-or.html
if (this.animator.GetCurrentAnimatorStateInfo(0).IsName("YourAnimationName"))
{
//your code here
}
this tells you if you are in a certain state.
Animator.GetCurrentAnimatorStateInfo(0).normalizedTime
this give you the normalized time of the animation: https://docs.unity3d.com/ScriptReference/AnimationState-normalizedTime.html
Try to play with those function, I hope that solve your problem
Making a little prototype at work and have been following some tutorials on how to do UI. Everything seems to be working except for the fact that hitting "space" while playing doesn't pause the game. I added some debug logs to try and catch where it was breaking, but I get no log output when hitting the space key. Which I think means something is breaking before or at the point where it should be looking for GetKeyDown.
In editor I have the Resume button and "Paused" text all set with the tag "ShowOnPause". If I comment out the hidePaused in the start function they appear correctly so I don't think it's a error in the editor.
If anyone sees anything else I could be doing better please share. Still trying to learn this stuff.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class UIManager : MonoBehaviour
{
// Array of gameObjects for the Pause Menu
GameObject[] pauseObjects;
void Start ()
{
//Game is running at start
Time.timeScale = 1;
// Assign all objects with the ShowOnPause to pauseObjects
pauseObjects = GameObject.FindGameObjectsWithTag("ShowOnPause");
//Hide all pause UI at start
hidePaused();
Debug.Log("UI Hidden");
}
void Update ()
{
// If the space key is pressed
if(Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Key Pressed");
// and if the game is running
if(Time.timeScale == 1)
{
// Pause the game and show Pause Menu
Time.timeScale = 0;
showPaused();
Debug.Log("Paused");
}
// or if the game is already paused
else if (Time.timeScale == 0)
{
// Resume the game and hide the Pause Menu
Time.timeScale = 1;
hidePaused();
Debug.Log("UnPaused");
}
}
}
// The function for activating gameobjects in the Pause Menu array
public void showPaused()
{
foreach(GameObject g in pauseObjects)
{
g.SetActive(true);
Debug.Log("Showing UI");
}
}
// The Function for deactivating the gameobjects in the Pause Menu array
public void hidePaused()
{
foreach(GameObject g in pauseObjects)
{
g.SetActive(false);
Debug.Log("Hiding UI");
}
}
// Function for the Resume button in the Pause Menu
public void Resume()
{
if(Time.timeScale == 1)
{
Time.timeScale = 0;
showPaused();
}
else if (Time.timeScale == 0)
{
Time.timeScale = 1;
hidePaused();
}
}
}
try this
if(Input.GetKeyDown("space"))
I have a game with four scenes, a menu scene, a loading scene, and two game scenes. All is well, when I am transitioning from my menu scene to my game scenes, but whenever I transition from my game scenes back to my menu scene or reload the game scene, the loading scene simply stops responding. I get a warning message that says "NetworkManager detected a script reload in the editor. This has caused the network to be shut down" only when I try to reload the currently active game scene. This issue is also present when I play in the build! I used print statements to trace down where my code stopped running, and I figured out that it was the Yield Return New WaitForSeconds() which caused the game to freeze. Why is that?
I have two scripts that controls transitioning. One simple script called on UIButtons for telling the second more complex script called in the preload scene to load the scene it's supposed to load and create animations. I have made sure that I was loading on to the correct scene, and that all of the scenes were added into my build settings.
The following pictures show the loading scene not responding. The first picture shows what happens when I try to reload the current game scene, and the second picture shows what happens when I try to load the menu scene:
My Loading Scene Script:
public class LoadingScreenManager : MonoBehaviour {
[Header("Loading Visuals")]
public Image loadingIcon;
public Image loadingDoneIcon;
public Text loadingText;
public Image progressBar;
public Image fadeOverlay;
[Header("Timing Settings")]
public float waitOnLoadEnd = 0.25f;
public float fadeDuration = 0.25f;
[Header("Loading Settings")]
public LoadSceneMode loadSceneMode = LoadSceneMode.Single;
public ThreadPriority loadThreadPriority;
[Header("Other")]
// If loading additive, link to the cameras audio listener, to avoid multiple active audio listeners
public AudioListener audioListener;
AsyncOperation operation;
Scene currentScene;
public static int sceneToLoad = -1;
// IMPORTANT! This is the build index of your loading scene. You need to change this to match your actual scene index
static int loadingSceneIndex = 1;
public static void LoadScene(int levelNum) {
Application.backgroundLoadingPriority = ThreadPriority.High;
sceneToLoad = levelNum;
SceneManager.LoadScene(loadingSceneIndex);
}
void Start() {
if (sceneToLoad < 0)
return;
fadeOverlay.gameObject.SetActive(true); // Making sure it's on so that we can crossfade Alpha
currentScene = SceneManager.GetActiveScene();
StartCoroutine(LoadAsync(sceneToLoad));
}
private IEnumerator LoadAsync(int levelNum) {
ShowLoadingVisuals();
yield return null;
FadeIn();
StartOperation(levelNum);
float lastProgress = 0f;
// operation does not auto-activate scene, so it's stuck at 0.9
while (DoneLoading() == false) {
yield return null;
if (Mathf.Approximately(operation.progress, lastProgress) == false) {
progressBar.fillAmount = operation.progress;
lastProgress = operation.progress;
}
}
if (loadSceneMode == LoadSceneMode.Additive)
audioListener.enabled = false;
ShowCompletionVisuals();
//THE PRINT STATEMENT WORKS FINE RIGHT HERE! The value of waitOnLoadEnd is only 1
yield return new WaitForSeconds(waitOnLoadEnd);
//THE PRINT STATEMENT STOPS RUNNING RIGHT HERE!
FadeOut();
yield return new WaitForSeconds(fadeDuration);
if (loadSceneMode == LoadSceneMode.Additive)
SceneManager.UnloadScene(currentScene.name);
else
operation.allowSceneActivation = true;
}
private void StartOperation(int levelNum) {
Application.backgroundLoadingPriority = loadThreadPriority;
operation = SceneManager.LoadSceneAsync(levelNum, loadSceneMode);
if (loadSceneMode == LoadSceneMode.Single)
operation.allowSceneActivation = false;
}
private bool DoneLoading() {
return (loadSceneMode == LoadSceneMode.Additive && operation.isDone) || (loadSceneMode == LoadSceneMode.Single && operation.progress >= 0.9f);
}
void FadeIn() {
fadeOverlay.CrossFadeAlpha(0, fadeDuration, true);
}
void FadeOut() {
fadeOverlay.CrossFadeAlpha(1, fadeDuration, true);
}
void ShowLoadingVisuals() {
loadingIcon.gameObject.SetActive(true);
loadingDoneIcon.gameObject.SetActive(false);
progressBar.fillAmount = 0f;
loadingText.text = "LOADING...";
}
void ShowCompletionVisuals() {
loadingIcon.gameObject.SetActive(false);
loadingDoneIcon.gameObject.SetActive(true);
progressBar.fillAmount = 1f;
loadingText.text = "LOADING DONE";
}
}
Script on UIButtons that call the above script:
public class LoadingSceneButton : MonoBehaviour {
public void LoadSceneWithLoadingScreen(int sceneNumber){
if (sceneNumber < 0 || sceneNumber >= SceneManager.sceneCountInBuildSettings) {
Debug.LogWarning ("Can't Load Scene, because It Doesn't Exist!");
}
LoadingScreenManager.LoadScene (sceneNumber);
}
}
(1) Don't use "print", please use this:
Debug.Log("fadeDuration is ....... " , fadeDuration.ToString("f4");
add that line of code just before you call FadeOut and also please add it inside FadeOut
(2) problems with CrossFadeAlpha
Please note that CrossFadeAlpha is extremely difficult to use! It's a real pain! It only works on UnityEngine.UI.Graphic, and it's tricky when used with coroutines.
public static void FadeOut(this Graphic g)
{
g.GetComponent<CanvasRenderer>().SetAlpha(1f);
g.CrossFadeAlpha(0f,.15f,false);
}
(3) problems with loading a scene in Unity5 !!!
Yes there is a
known issue
where it gets stuck on 0.9. Maybe this is the main problem at hand.
check out ... http://answers.unity3d.com/answers/1146173/view.html
and ... http://answers.unity3d.com/answers/1073667/view.html
Some basic working code example....
public void LaunchSoundboard()
{
StartCoroutine(_soundboard());
}
private IEnumerator _soundboard()
{
Grid.music.Duck();
yield return new WaitForSeconds(.2f);
AsyncOperation ao;
ao = UnityEngine.SceneManagement
.SceneManager.LoadSceneAsync("YourSceneName");
while (!ao.isDone)
{
yield return null;
}
// here, the new scene IS LOADED
SoundBoard soundBoard = Object.FindObjectOfType<SoundBoard>();
if(soundBoard==null) Debug.Log("WOE!");
soundBoard.SomeFunctionInSoundboardScript();
}
Note that you wait on ".isDone", rather than watch the float.
(4) #You actually have to have a scene called "preload", which ONLY preloads.
unfortunately the menu scene can not be your preload scene.
You have to actually have a separate preload scene which does nothing but that, "preload".
Note that any "game managers" you have must be on the preload scene. It's a bit annoying but that's how it is.
The purpose of the "preload" scene is to hold any game managers you have.
The only scene that you mark "don't destroy on load" must be only the "preload" scene. It's that simple.
It's a bit of a nuisance but very simple and reliable.
I was trying to create a start menu to my unity game when I found this script that enables a hidden sprite as soon as the game starts. The script then disables it when the player presses the left mouse button or space. When I try to make multiple sprites show up and the disappear, using the same script, only one sprite appears. I'm also trying to find a way to change the scipt so that the payer have to click on the actual sprite to disable it instead of just pressing the space key.
This is the script:
using UnityEngine;
using System.Collections;
public class StartScreen : MonoBehaviour {
static bool sawOnce = false;
// Use this for initialization
void Start () {
if(!sawOnce) {
GetComponent<SpriteRenderer>().enabled = true;
Time.timeScale = 0;
}
sawOnce = true;
}
// Update is called once per frame
void Update () {
if(Time.timeScale==0 && (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) ) {
Time.timeScale = 1;
GetComponent<SpriteRenderer>().enabled = false;
}
}
}
It sounds as if you are looking to do something like this: http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseDown.html
Also, I always create a separate scene for my main menu systems, as they have done in that link.