I am currently creating a hidden object game and I have been stuck on how to add a timer and countdown to my game. I have currently a score which generates after all of the objects have been clicked however I would love if the score went up gradually once the user clicked on each one. here is my code below so far.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class trackingclicks : MonoBehaviour {
//static variable added to count users clicks
public static int totalclicks=0;
//"mouseclick" keycode variable to look for mouse click
public KeyCode mouseclick;
public Transform scoreObj;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//checks the change in time, aka how much time has passed- bonus time starts at 90
clickcontrol.timeBonus -= Time.deltaTime;
if (clickcontrol.remainItems == 0)
{
clickcontrol.totalScore += (70 + (Mathf.RoundToInt(clickcontrol.timeBonus)));
scoreObj.GetComponent<TextMesh>().text = "Score : " + clickcontrol.totalScore;
clickcontrol.remainItems = -1;
}
//Check for mouse click
if (Input.GetKeyDown (mouseclick))
{
totalclicks += 1;
}
if (totalclicks >= 5)
{
Debug.Log ("FAIL!!!");
totalclicks = 0;
}
}
}
You can use coroutines for timers (coroutines execute code after a certain amount of time). If you want your score to increment gradually once the player clicks on an object (I think that's what you're asking), then something like this should work:
public int score;
IEnumerator IncrementScore(int amount, int interval) { //amount is the amount of score to add over the time, interval is the time IN SECONDS between adds
for (int i = 0; i < amount; i++) {
yield return new WaitForSeconds(interval);
score++;
}
}
I wasn't sure where the score variable was so I made a new one; you can set it to your own, wherever it is. If you need more help, feel free to ask.
Related
I'm making a game currently and I got stuck while I was thinking about a combotimer.
Now in my game, there are enemies that run through my character and I hit them. Yet, at some point, if I can correctly hit the enemies, I want to add a powerful combo option like hitting them without any difficulty. I thought like I can create a class or a value that keeps the correct hits and let's say it's 5. When it reaches 5, then I can change the hitting options. Yet, where I'm stuck is that how I can identify after how many hits or seconds the combo can end. And in here what came to my mind is that I can make it with time. So here's the thing. I want to detect 5 hits and then I want a combotimer which makes the value of 5 decreased. So that when the value reaches 0 then I can continue to play my game with the normal standards of it. How can I do this?
Since you didn't provide anything here is what I would do as dummy code. This does
Everytime you hit an enemy check the time since last hit
If under the maximum delay => add to combo
If not reset the combo counter and start over
If reaching enough hits => enable isSuperCombo
Over time reset the isSuperCombo
As long as you are isSuperCombo you can still add hits even if they happen after the normal maxTimeBetweenHits to enlarge the duration of isSuperCombo as a little bonus
Something like
public class ComboCounter : MonoBehaviour
{
public bool isSuperCombo;
// Maimum delay in seconds since the hit for counting the current hit as combo
[SerializeField] private float maxTimeBetweenHits = 1;
// Requried hits in one combo in order to activate power bonus
[SerializeField] private int hitsUntilSuperCombo = 5;
// Delay in seconds to reset the powerup after the last hit
[SerializeField] private float powerUpDuration = 5;
private int hitCounter;
private float lastHitTime;
private float powerUpResetTimer;
private void Update()
{
if(isSuperCombo)
{
powerUpResetTimer -= Time.deltaTime;
if(powerUpResetTimer <= 0)
{
isSuperCombo = false;
hitCounter = 0;
}
}
}
// Call when you hit an enemy
public void AddHit()
{
if(Time.time - lastHitTime < maxTimeBetweenHits)
{
// then add to the hit counter
hitCounter++;
if(hitCounter >= hitsUntilSuperCombo)
{
isSuperCombo = true;
powerUpResetTimer = powerUpDuration;
}
}
else
{
// otherwise the delay was too big => not a combo anymore
// => Reset the counter and start over with this hit as the first one
hitCounter = 1;
}
// update the lastHitTime
lastHitTime = Time.time;
}
}
Then you could e.g. in another class check something like
public void CauseDamage(Enemy enemy)
{
enemy.health -= GetComponent<ComboCounter>().isSuperCombo ? 4 : 1;
}
If you need to note 5 seconds of increased damage you can use coroutine
private float _damage = 10;
public void StartCombo(float duration = 5)
{
StartCoroutine(ComboHandler(duration));
}
private IEnumerator ComboHandler(float duration)
{
_damage *= 2; //_damage = _damage * 2;
yield return new WaitForSeconds(duration); //wait necessary amount of real time
_damage /= 2; //_damage = _damage / 2;
}
If you need to do only 5 blows with increased damage, you can use something
private float _damage = 10;
private int _increasedBlows = 0; //amount of blows with increased damage
private float _increasingCoeff = 2; //ratio of damage increase of blow
//add new increased blows after doing combo
public void AddIncreasedBlows(int amount)
{
_increasedBlows += amount;
}
//return blow damage
public float GetHitDamage()
{
if (_increasedBlows > 0)
{
_increasedBlows--;
return _damage * -_increasingCoeff; //return increased damage
}
else
{
return _damage; //return usual damage
}
}
I have a game where I have time to give energy. My timer works fine when game is active but when game is inactive the time pauses and after I start game again the timer starts from wher it was left.
I want keep timer going even if the game is inactive and add energy.
using System;
using UnityEngine;
using UnityEngine.UI;
public class EnergyAdder : MonoBehaviour
{
// Start is called before the first frame update
public float waitTime = 600;
Timer timer;
public GameRoot gameRoot;
void Awake()
{
//timer = new Timer(waitTime);
float remainingTime = PlayerPrefs.GetFloat("TimeOnExit");
timer = new Timer(remainingTime);
}
// Update is called once per frame
void Update()
{
if (gameRoot.energyCap >= 5)
{
GetComponent<Text>().text = "Full";
timer.refresh();
}
else
{
timer.countDown();
if (timer.isFinished())
{
timer = new Timer(waitTime);
timer.refresh();
gameRoot.AddEnergy(1);
}
UpdateClock();
}
}
void UpdateClock()
{
int seconds = ((int)timer.timeLeft) % 60;
int minutes = (int)(timer.timeLeft / 60);
GetComponent<Text>().text = minutes.ToString() + ":" + seconds.ToString("00");
}
void OnApplicationQuit()
{
PlayerPrefs.SetFloat("TimeOnExit", timer.timeLeft);
}
}
Please help I'm new to unity and c#.
What you are doing is saving time value when you left, and load that value when you start the game again.
Maybe you should (when start the game) compare that loaded time with the current time, the difference will be the time elapsed.
When the player dies, one heart is removed from the health bar. A cool down timer starts that will refill the heart after 5 minutes. If the player should die again, the second heart will be removed but the timer will first finish its current cool down before restarting.
When the player dies the second time, the scene reloads and a countdown is shown to give the player time to get ready for the next try.
The problem is as soon as the countdown is finished and the timescale is set to 1, the cool down timer speed increases. If he dies again the timer speed increases again, till the first cool down timer completes and then resets and start the next cool down, then the speed is back to normal or if I exit the game and re-enter the timer is back to normal.
When the scene loads the timescale is 0. The countdown animation runs using a Mycoroutine script. After the animation is finished the timescale is set back to 1.
The cool down timer takes into account the time that a player is offline using a TimerMaster script and works 100%. Tested it on android and if the game moves to the background the timer works fine, using Time.unscaledDeltaTime instead of Time.DeltaTime.
The only problem I can't figure out is the speed increase every time the level restarts.
//this is used to call the countdown
public bool setCoundown = false;
void Start()
{
countDown.SetActive(true); //when active it sets setCountdown to true
Time.timeScale = 0;
}
void Update()
{
if (setCoundown)
{
StartCoroutine(CountDown()); //set the timer to wait till the countdown is done
}
}
IEnumerator CountDown()
{
while (setCoundown == true)
{
yield return StartCoroutine(Mycoroutine.WaitforRealSeconds(0.5f));
setCoundown = false;
Time.timeScale = 1;
RunGame();
}
}
//This script is called by CountDown()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Mycoroutine
{
public static IEnumerator WaitforRealSeconds(float time)
{
float start = Time.realtimeSinceStartup;
while(Time.realtimeSinceStartup < (start + time))
{
yield return null;
}
}
}
//This is the cool down timer
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class TimerText : MonoBehaviour
public static TimerText instance;
[SerializeField]
private Text timeText;
private int health;
private float timer, minutes, seconds;
void Start()
{
//get saved time that was needed to fill all health
timer = GameController.instance.GetTimerTime();
//deduct the offline time from the needed time
timer = timer - TimerMaster.instance.CheckDate();
//call the function to calculate offline time and set lives and timer value accordingly if the health is full then the timer value will be 300
DateTimer();
}
void Update()
{
health = GameController.instance.GetHealth();
if (health < 3 && timeText.text == "0:00")
{
StartCoundownTimer();
}
}
void StartCoundownTimer()
{
if (timeText != null)
{
timeText.text = "0:00";
InvokeRepeating("UpdateTimer", 0.0f, 0.01667f);
}
}
void UpdateTimer()
{
if (timeText != null)
{
timer -= Math.Max(Time.unscaledDeltaTime, 0);
timeText.text = string.Format("{0}:{1:00}", (int)(timer / 60), (int)(timer % 60));
if (timeText.text == "0:00")
{
CancelInvoke();
health = GameController.instance.GetHealth() + 1;
GameController.instance.SetHealth(health);
timer = 300;
}
}
}
I am trying to use this script to set a timer for someone looting a player however i can't get it to reset after i call it a second time but it stores the original value of time left where as i want it to start fresh each time.
i am calling it from another script which enables and disables it on the OnTriggerEnter and OnTriggerExit methods
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Changetext : MonoBehaviour {
public float timeLeft = 5;
public Text countdownText;
public float cash = 0;
// Use this for initialization
void start()
{
timeLeft = 5;
}
void Update()
{
timeLeft -= Time.deltaTime;
countdownText.text = ("Time Left = " + timeLeft);
if (timeLeft <= 0)
{
countdownText.text = "You got the cash";
cash = 1;
}
}
}
Start() only gets called once in the gameobjects lifetime - so it won't toggle everytime you enable/disable.
You can instead use OnEnable() to reset the timer to 5;
void OnEnable()
{
timeLeft = 5;
}
(as an FYI, Start() needs a capital 'S')
I have this timer in my unity game that is a simple countdown timer that when certain function is completed reset the time to default and increments the time by 1 seconds. It works fine but when I increment by 3 seconds, it doesn't increment.
Here is the code:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using GooglePlayGames;
using GooglePlayGames.BasicApi;
public class GameLogic : MonoBehaviour
{
public int[] sequence; //The sequence int array will hold our sequence order
public int sequenceLength; //The sequenceLength is how long a sequence will be. Everytime the player completes a sequence it goes up one
public int sequencesPlayedCom; //The sequencesPlayedCom is to measure how many times the computer has pressed the buttons in the current sequence
public int sequencesPlayedPlayer; //The sequencesPlayedPlayer is to measure how many times the player has pressed the buttons in the current sequence
public float timeleft = 5.0f;
public float timecounter;
public int score; //Each time the player completes a sequence they get +1 onto their score
public int casualHighScore; //This variable holds the highest score that the player has ever achieved on the casual gamemode
public int randomizeHighScore; //This variable holds the highest score that the player has ever achieved on the randomize gamemode
public string gameMode; //This will tell us what game mode the player chose so we can modify the game (casual, randomize)
//Buttons
public GameObject greenButton; //This holds the GameObject of our green button, so that the script can send messages over to it
public GameObject redButton; //This holds the GameObject of our red button, so that the script can send messages over to it
public GameObject blueButton; //This holds the GameObject of our blue button, so that the script can send messages over to it
public GameObject yellowButton; //This holds the GameObject of our yellow button, so that the script can send messages over to it
//UI
public Text scoreText; //This is the text that is displayed on screen, that tells us our score
public Text highScoreText; //Just like the score text, but displaying the high score
//Sounds
public AudioSource audioSource; //This is the source of which we will play the sequence fail and complete sounds through
public AudioClip sequenceCompleteSound;
public AudioClip sequenceFailSound;
public AudioClip buttonClickSound;
void Start () //The Start function is called on the frame that the script becomes active
{
gameMode = PlayerPrefs.GetString("GameMode"); //We need to access our game mode that the player selected
casualHighScore = PlayerPrefs.GetInt("CasualHighScore"); //We need to access our saved score
randomizeHighScore = PlayerPrefs.GetInt("RandomizeHighScore");
audioSource = GameObject.Find("Camera").GetComponent<AudioSource>();
audioSource.volume = PlayerPrefs.GetFloat("Volume"); //We are setting our volume to the one that we set in the options menu
sequence = new int[50]; //Here we are defining the sequence array's size
timecounter = timeleft;
StartCoroutine(GenerateNextSequence()); //We call the GenerateNextSequence function which randomly selects the next number for the sequence
}
void Update () //The Update function is called once per frame
{
scoreText.text = "SCORE\n" + score; //Here we are setting what our on screen text will say. The '\n' basically makes a new line
if(gameMode == "casual"){
highScoreText.text = "HIGH SCORE\n" + casualHighScore; //Just like the on screen score text, but displaying the high score for the casual gamemode
}
else if(gameMode == "randomize"){
highScoreText.text = "HIGH SCORE\n" + randomizeHighScore; //Just like the on screen score text, but displaying the high score for the randomize gamemode
}
timer();
}
public void timer()
{
if (timecounter > 0)
{
timecounter -= Time.deltaTime;
Debug.Log(timecounter);
} else
{
audioSource.PlayOneShot(sequenceFailSound); //Since the player failed the sequence, we need to play the appropriate sound
SaveScore();
Application.LoadLevel(0); //Since the player we load up the menu
}
}
IEnumerator GenerateNextSequence ()
{
sequencesPlayedCom = 0; //Set the number of times that the computer has clicked a button to 0
sequencesPlayedPlayer = 0; //Set the number of times that the player has clicked a button to 0
timecounter = timeleft;
timecounter = timecounter + 3;
if (gameMode == "casual"){
sequence[sequenceLength - 1] = Random.Range(1, 5); //Since array index's start at 0, we have it randomly select a number between 1 and 5 (it rounds to the nearest int) and set it to the most current index number.
yield return new WaitForSeconds(1); //We wait 1 second after picking our next colour, before going on to playing the sequence
StartCoroutine(PlaySequence()); //Now that we have our next colour, we can go and play the array to the player
}
else if(gameMode == "randomize"){
for(int i = 0; i < sequenceLength; i ++){
sequence[i] = Random.Range(1, 5);
}
yield return new WaitForSeconds(1);
StartCoroutine(PlaySequence()); //Now that we have our random sequence, we can have the computer play it
}
}
IEnumerator PlaySequence () //Plays the sequence
{
CanClickButton(false); //We call a function that disables the buttons while the computer is playing the sequence
while(sequencesPlayedCom < sequenceLength){ //A while loop. Here we have it continuously do what is inside the brackets as long as sequencesPlayedCom < sequenceLength
GameObject buttonToPress = null; //We set this temporary GameObject variable to hold the button so its ButtonPress function can be called
if(sequence[sequencesPlayedCom] == 1){ //If the next element in the int array is 1 then it will be a green button
buttonToPress = greenButton;
}
else if(sequence[sequencesPlayedCom] == 2){
buttonToPress = redButton;
}
else if(sequence[sequencesPlayedCom] == 3){
buttonToPress = blueButton;
}
else if(sequence[sequencesPlayedCom] == 4){
buttonToPress = yellowButton;
}
buttonToPress.SendMessage("ButtonPress"); //We call the ButtonPress function on the button so the player can see and hear it
yield return new WaitForSeconds(0.7f); //Wait 0.7 seconds until we continue to the next colour in the sequence
sequencesPlayedCom++; //Adding one to the sequencesPlayedCom so we know that computer just clicked a button
}
if(sequencesPlayedCom == sequenceLength){
CanClickButton(true); //After the computer has pressed all the buttons in the sequence, the player can now click on the buttons
}
}
IEnumerator CheckSequenceButton (int id)
{
if(sequence[sequencesPlayedPlayer] == id){ //We check to see if the next color of the sequence is the one that the player pressed
sequencesPlayedPlayer ++;
}else{
yield return new WaitForSeconds(0.3f);
audioSource.PlayOneShot(sequenceFailSound); //Since the player failed the sequence, we need to play the appropriate sound
SaveScore();
yield return new WaitForSeconds(1.7f); //A delay after the player fails
Application.LoadLevel(0); //Since the player we load up the menu
}
if(sequencesPlayedPlayer == sequenceLength){ //If the player has completed the sequence
yield return new WaitForSeconds(0.3f); //We have a small delay after the player completes the sequence
audioSource.PlayOneShot(sequenceCompleteSound);
score++; //Since the player has completed the sequence, we will add 1 to the score
sequenceLength++; //The sequence length is one added to it
StartCoroutine(GenerateNextSequence()); //We continue on with this loop, increasing the sequence one colour at a time
}
}
public void GoToMenu () //Function used to get back to the main menu
{
audioSource.PlayOneShot(buttonClickSound); //Playing the button click sound
SaveScore();
Application.LoadLevel(0);
}
void CanClickButton (bool i) //Tells the buttons if they can be clicked or not
{
greenButton.SendMessage("DisableOrEnableButton", i);
redButton.SendMessage("DisableOrEnableButton", i);
blueButton.SendMessage("DisableOrEnableButton", i);
yellowButton.SendMessage("DisableOrEnableButton", i);
}
void SaveScore () //Checks if score is higher that high score then saves it to Player Prefs
{
if(gameMode == "casual"){ //If the game mode is Casual
if(score > casualHighScore){ //If the players current score is higher than their highscore then we will change it
PlayerPrefs.SetInt("CasualHighScore", score);
if (PlayGamesPlatform.Instance.localUser.authenticated)
{
// Note: make sure to add 'using GooglePlayGames'
PlayGamesPlatform.Instance.ReportScore(score,
GPGSlds.leaderboard_facil,
(bool success) =>
{
Debug.Log("(Lollygagger) Leaderboard update success: " + success);
});
}
}
}
else if(gameMode == "randomize"){
if(score > randomizeHighScore){
PlayerPrefs.SetInt("RandomizeHighScore", score);
if (PlayGamesPlatform.Instance.localUser.authenticated)
{
// Note: make sure to add 'using GooglePlayGames'
PlayGamesPlatform.Instance.ReportScore(score,
GPGSlds.leaderboard_normal,
(bool success) =>
{
Debug.Log("(Lollygagger) Leaderboard update success: " + success);
});
}
}
}
}
}
I miss some code that doesn't have to do with the timer, the timer work fine, just that I can't do the autoincrement when the function GenerateNextSequence() is run.