I've made a unity3d game and I want to add UI . I've started with a pause button but it doesn't seem to work.
Here is the button info:
I've created an uiManager script to manage the button , as shown in the image above and here is the code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class myUIManager : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void Pause() //Function to take care of Pause Button..
{
print("Entered Pause Func");
if (Time.timeScale == 1 && paused == false) //1 means the time is normal so the game is running..
{
print("Enterer first if");
Time.timeScale = 0; //Pause Game..
}
if (Time.timeScale == 0)
{
Time.timeScale = 1; //Resume Game..
}
}
}
Here is the canvas screenshot :
Any ideas? I've been searching for hours ..
I think your problem is in your Pause method:
public void Pause() //Function to take care of Pause Button..
{
print("Entered Pause Func");
if (Time.timeScale == 1 && paused == false) //1 means the time is normal so the game is running..
{
print("Enterer first if");
Time.timeScale = 0; //Pause Game..
}
if (Time.timeScale == 0)
{
Time.timeScale = 1; //Resume Game..
}
}
If you enter the first if statement you set Time.timeScale = 0 - and then you immediately go into the second if and set it back to 1.
Try this - it returnss from the Pause method once it sets the Time.timeScale to 0.
public void Pause() //Function to take care of Pause Button..
{
print("Entered Pause Func");
if (Time.timeScale == 1 && paused == false) //1 means the time is normal so the game is running..
{
print("Enterer first if");
Time.timeScale = 0; //Pause Game..
return;
}
if (Time.timeScale == 0)
{
Time.timeScale = 1; //Resume Game..
}
}
If the only two things you want to do in your Pause method are to set the Time.timeScale to 0 or 1, you could even simplify it to this:
public void Pause() //Function to take care of Pause Button..
{
print("Entered Pause Func");
if (Time.timeScale == 1 && paused == false) //1 means the time is normal so the game is running..
{
print("Enterer first if");
Time.timeScale = 0; //Pause Game..
}
else
{
Time.timeScale = 1; //Resume Game..
}
}
if the condition of your first if statement is true then you set your timeScale to 0 then the condition of the second if becomes true then you set it back to 1 You should just change your second if to an else if so that if the first condition is true then your program wont check the second one.
public void Pause()
{
if (Time.timeScale == 1)
{
Time.timeScale = 0;
}
else if (Time.timeScale == 0)
{
Time.timeScale = 1; //Resume Game..
}
}
Related
how do I add a countdown from 5 to 1 right after my game ends?
I tried using this `
int countdownStartValue = 5;
void start()
{
}
void countdownTimer()
{
if (countdownStartValue > 0)
{
countdownStartValue--;
Invoke('countdownTimer', 1.0f);
countdownTimer();
}
}
but it seems to be wrong
I would just use Thread.Sleep() in this case.
int countdownStartValue = 5;
void start()
{
}
void countdownTimer()
{
while (countdownStartValue > 0)
{
countdownStartValue--;
Thread.Sleep(1000);
}
}
The current running thread (program) will sleep for 1 second before continuing to run
I am trying to implement two touch functions. One tap and long tap. I have implemented one tap which is pretty straightforward but for a long tap function, a timer must be set?
I would like the long press to be active only after 1 second of holding the tap and then the timer should get reset on release. How do I do this?
public float longTapTime;
void Update()
{
if ((Input.touchCount > 0) && (Input.GetTouch (0).phase == TouchPhase.Began)) {
//One tap
}
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
{
longTapTime = 0;
}
}
using UnityEngine;
public class example : MonoBehaviour
{
[SerializeField]
private float long_tap_consider_duration = 1.0f;
private float time_helper;
private float duration;
private bool is_touched;
private void Start()
{
time_helper = 0;
duration = 0;
is_touched = false;
}
private void Update()
{
if (Input.touchCount > 0)
ProcessInput();
}
private void ProcessInput()
{
if (is_touched && ((Input.GetTouch(0).phase == TouchPhase.Ended) || (Input.GetTouch(0).phase == TouchPhase.Canceled)))
{
if (duration > long_tap_consider_duration)
OnLongTap();
else OnTap();
}
if (!is_touched && (Input.GetTouch(0).phase == TouchPhase.Began))
{
time_helper = Time.time;
is_touched = true;
}
duration = Time.time - time_helper;
}
//Callback function, when just a short tap occurs
private void OnTap()
{
Debug.Log("Short Tap");
}
//Callback function, when long tap occurs
private void OnLongTap()
{
Debug.Log("Long Tap");
}
}
actually, if you are using the new input system, this is a built in feature and does not need any code.
find your Input Actions ".inputActions"
find the button on the list of inputs registered
with that item selected, find the plus "+" next to the word interactions on the right hand side
add a "hold" interaction from the list and set desired hold time.
for more information on the input action asset system: https://www.youtube.com/watch?v=mvuXOyKz7k4
I'm making a endless runner game. And would like to increase the health/life when a certain score has reached. In a ScoreManager script attached to a ScoreManager I have:
public class ScoreManager : MonoBehaviour
{
public int score;
public Text scoreDisplay;
bool one = true;
Player scriptInstance = null;
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Obstacle"))
{
score++;
Debug.Log(score);
}
}
// Start is called before the first frame update
void Start()
{
GameObject tempObj = GameObject.Find("ghost01");
scriptInstance = tempObj.GetComponent<Player>();
}
// Update is called once per frame
private void Update()
{
scoreDisplay.text = score.ToString();
if (scriptInstance.health <= 0)
{
Destroy(this);
}
if (score == 75 || score == 76 && one == true)
{
scriptInstance.health++;
one = false;
}
}
I used the following lines to increase the health at a milestone, but have to copy the code endlessly to create multiple milestones.
if (score == 75 || score == 76 && one == true)
{
scriptInstance.health++;
one = false;
}
My question is how to increase health every 75 points, without duplicating the code?
The issue with a modulo like if(score % 75 == 0) would be that it returns true all the time while score == 75 .. so it would require an additional bool flag anyway.
I would rather simply add a second counter for this!
And not check things repeatedly in Update at all but rather the moment you set it:
int healthCounter;
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Obstacle"))
{
score++;
Debug.Log(score);
// enough to update this when actually changed
scoreDisplay.text = score.ToString();
healthCounter++;
if(healthCounter >= 75)
{
scriptInstance.health++;
// reset this counter
healthCounter = 0;
}
}
}
the one drawback maybe is that know you have to reset the healthCounter = 0 wherever you reset the score = 0 ... but you would have to do the same with any flag solution as well ;)
I would go with th % operator
private bool scoreChanged = false;
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Obstacle"))
{
score++;
scoreChanged = true;
Debug.Log(score);
}
}
if (score % 75 == 0 && scoreChanged)
{
scriptInstance.health++;
scoreChanged = false;
}
I'm making a game and I want jumping to feel like jumping in Super Mario Bros. I'm able to get the result I want with a Keyboard or a Controller because they have KeyDown, Key (While pressed), and KeyUp. But touchButtons only have a single boolean. (Pressed or Not Pressed) Is there a way I can work around this?
I tried using Input.GetTouch and using the begin and end phase, this gave the correct result but I'm not sure how to implement it into a GUI button.
The code I'm using has a GUI button with a script that when the button is pressed, joybutton.Pressed = true
void PlayerJump()
{
bool canJump = charController.isGrounded;
//Button Pressed start jumpDuration
if (joybutton.Pressed && canJump)
{
isJumping = true;
jumpDuration = jumpTime;
}
if (isJumping == true)
{
if (jumpDuration > 0)
{
vertical_Velocity = jump_Force;
jumpDuration -= Time.deltaTime;
}
//timer runs out
else
{
isJumping = false;
}
}
//cancel jump if mid-air
if (!joybutton.Pressed)
{
isJumping = false;
}
}
I have no way of stopping the player from jumping as soon as they land with the GUI touchButton. I get desired results with keyboard and gamepad buttons.
Add a variable to remember the state of the button last frame. That way, you can enter the jump start block only if it's the first frame of the button being hit:
private bool wasJumpPressedLastFrame = false;
void PlayerJump()
{
bool canJump = charController.isGrounded;
//Button Pressed start jumpDuration
if (joybutton.Pressed && canJump && !wasJumpPressedLastFrame )
{
isJumping = true;
jumpDuration = jumpTime;
}
if (isJumping == true)
{
if (jumpDuration > 0)
{
vertical_Velocity = jump_Force;
jumpDuration -= Time.deltaTime;
}
//timer runs out
else
{
isJumping = false;
}
}
//cancel jump if mid-air
if (!joybutton.Pressed)
{
isJumping = false;
}
wasJumpPressedLastFrame = joyButton.Pressed;
}
I want to show ads in my 2D game every 5 times the scene is loaded. I tried this:
void Update ()
{
if(GameObject.Find ("Main Camera").transform.position.x == -23) {
showNumber += 1;
if(showNumber == 5) {
if(Advertisement.isReady()){
Advertisement.Show();
}
}
if(showNumber > 5) {
showNumber = 1;
}
}
}
How do I make the number only change only once so it would only change once when the main camera's position is -23. Right not it changes every frame.
Edit
void OnTriggerEnter(Collider other) {
DontDestroyOnLoad (gameObject);
if(other.name == "Main Camera") {
showNumber +=1;
if(showNumber == 5) {
if(Advertisement.isReady()){
Advertisement.Show();
}
}
if(showNumber > 5) {
showNumber = 0;
}
}
}
Solution: Put the showNumber +=1 oder showNumber++ into
void Start()
{
showNumber +=1;
}
I think it would be easier if you write this value to a textfile and then read it from this textfile, all in the start event and not the update.
Start is called once and the update is called every frame.
Quick and dirty Edit: Place a trigger zone on your desired postion.
Then call an OnTriggerEnter method.
void OnTriggerEnter(Collider other) {
showNumber +=1;
if(showNumber == 5) {
if(Advertisement.isReady()){
Advertisement.Show();
}
}
Edit: Your problem is that showNumber +=1; is called like 30-60 times, depending on your computer.
You could add a bool variable to check if it's a new entry on that point.
bool alreadyEntered = false;
void Update ()
{
if(GameObject.Find ("Main Camera").transform.position.x == -23 && alreadyEntered == false) {
showNumber += 1;
alreadyEntered = true;
if(showNumber == 5) {
if(Advertisement.isReady()){
Advertisement.Show();
}
}
if(showNumber > 5) {
showNumber = 1;
}
}
}
Save the Show Number in player prefs.
private int showNumber{
get{
return PlayerPrefs.GetInt("showNumber");
}
set{
PlayerPrefs.SetInt("showNumber",value);
}
}
void OnTriggerEnter(Collider other) {
showNumber +=1;
if(showNumber == 5) {
if(Advertisement.isReady()){
Advertisement.Show();
showNumber = 0;
}
}