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"))
Related
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
}
}
}
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
I writing runner game on Unity (C#) for mobile phones.
I made Pause button on screen, using Canvas - Button.
Also I made code for Pause in Platformer2DUserControl script.
Here it is code of this script:
using UnityEngine;
using UnitySampleAssets.CrossPlatformInput;
namespace UnitySampleAssets._2D
{
[RequireComponent(typeof(PlatformerCharacter2D))]
public class Platformer2DUserControl : MonoBehaviour
{
private PlatformerCharacter2D character;
private bool jump;
public bool paused;
private void Awake()
{
character = GetComponent<PlatformerCharacter2D>();
paused = false;
}
private void Update()
{
/*if (Input.GetButton("Fire1"))
{
}*/
if (!jump)
// Read the jump input in Update so button presses aren't missed.
jump = Input.GetButton("Fire1"); //&& CrossPlatformInputManager.GetButtonDown("Jump");
}
private void FixedUpdate()
{
// Read the inputs.
bool crouch = Input.GetKey(KeyCode.LeftControl);
// float h = CrossPlatformInputManager.GetAxis("Horizontal");
// Pass all parameters to the character control script.
character.Move(1, false, jump);
jump = false;
}
public void Pause()
{
if (!jump)
// Read the jump input in Update so button presses aren't missed.
jump = Input.GetButton("Fire1"); //&& CrossPlatformInputManager.GetButtonDown("Jump");
paused = !paused;
if (paused)
{
jump = !jump;
Time.timeScale = 0;
}
else if (!paused)
{
// jump = Input.GetButton("Fire1");
Time.timeScale = 1;
}
}
}
}
My Pause Button is WORKS well. But when I tap it , my character is jumping and game is pausing.
I want to make that , when I tapping the button game just pausing and character don't jump.
How I can make it. Thank's for help.
I would advise you not to use the same input for jumping and pausing. Also, separate your jump and pause functionalities into separate functions. For pausing, create a UI button on the screen and make it call a public function on a Pause script, that will toggle pause. Then, in the same function, check if you are paused or not and adjust Time.timescale accordingly
You will have to attach the script with pause functionality on to an object that will always be in a screen (Say, a panel in your canvas or your MainCamera). Under the button, add a new onClick() function after dragging the GO with the apt script to the box. Then, select the public function aforementioned.
private bool paused = false;
//The function called by the button OnClick()
public void TogglePause()
{
paused = !paused;
if(paused)
Time.timescale = 0f;
else
Time.timescale = 1f;
}
Hope this helped!
Well, your code is messed up, but just remove the jump script from the pause method. So it will just pause...
public void Pause()
{
paused = !paused;
if (paused)
{
Time.timeScale = 0;
}
else
{
Time.timeScale = 1;
}
}
Note that Input.GetButton should only be called in Update
EDIT
The problem that you have to tap your screen to press the button. And the code jump = Input.GetButton("Fire1"); basically means "Am I tapping the screen?" So both JUMP and PAUSE are triggered.
One solution would be to put a canvas filling the whole screen under your buttons. You will trigger a JUMP action only when this canvas is clicked. So when you click your pause button, it will stop the propagation and won't click the full screen canvas, which won't trigger the jump action.
EDIT2
Try changing the lines (in the Update function) :
if (!jump)
// Read the jump input in Update so button presses aren't missed.
jump = Input.GetButton("Fire1");
for :
if (!jump && !paused)
// Read the jump input in Update so button presses aren't missed.
jump = Input.GetButton("Fire1");
I think the button event is called before the Update, see reference
One solution would be possible make sure the raycast on of pause button.
I have always done it like this, essentially surround the entire fixed update (or wherever you have your game motion) with the paused-bool
private void FixedUpdate()
{
if (paused != true){
// Read the inputs.
bool crouch = Input.GetKey(KeyCode.LeftControl);
// float h = CrossPlatformInputManager.GetAxis("Horizontal");
// Pass all parameters to the character control script.
character.Move(1, false, jump);
jump = false;
}
}
I'm making game with Unity and I'm using SceneManager.LoadScene for loading from main scene to play scene. Everything is fine, but it takes too long time. So, game move from main scene to play scene but there is a slider between two scenes.
This is my code:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Load : MonoBehaviour
{
public Slider LoadSlider;
public Text percentSlider;
void Start ()
{
InvokeRepeating ("AdLoadPercent", 0.01f, 0.4f);
}
public void AdLoadPercent()
{
LoadSlider.value += Random.Range(0.6f,0.9f);
percentSlider.text=Mathf.RoundToInt(LoadSlider.value*100).ToString() + " %";
if (LoadSlider.value >= 1f)
{
SceneManager.LoadScene ("Scena1");
}
}
}
Why it take so long when my slider is equal 1?
" long " means that I have to wait more than 15 seconds.
Thanks and kind regards
Is it the same without using the slider?
I haven't used InvokeRepeating, never even heard about it in fact, so there's a chance that there's something going on with this function.
Place LoadScene() line in the Start() function and see if this helps. If it switches scenes instantly (or almost, like in < 1.25s) it's a problem with your repeating function. For things like that I recommend using an Update() function or an IENumerator
Example #1:
bool loadingStarted = false;
void Start()
{
loadingStarted = true;
}
void Update()
{
if(loadingStarted)
{
progressbar.value += Time.deltaTime*0.25f;
//.. and so on ...
}
}
Example #2:
void Start()
{
StartCoroutine(Countdown());
}
IENumerator Countdown()
{
while(progressBar.value < 1f)
{
//Do your incrementation here...
if(progressBar.value >= 1f) break;
return yield new WaitForEndOfFrame(); //or WaitForSeconds(0.05);
}
}
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.