hi, with the following script , game level time is calculated and displayed.
however how may i have also the best time also available?
for the bet time there is a ui text and i cannot figure it out how to pass the most lowest time when user could win the current game level.
here is the script :
public class GameLevelInfo : MonoBehaviour
{
[SerializeField]
private Text moneyAmountText;
[SerializeField]
private Text gameTimeText;
[SerializeField]
private Text gameBestTimeText;
public static float timer;
private void Update()
{
timer += Time.deltaTime;
int minutes = Mathf.FloorToInt(timer / 60F);
int seconds = Mathf.FloorToInt(timer - minutes * 60);
gameTimeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
moneyAmountText.text = GlobalValues.money.ToString();
}
}
as soon as game level is over or it is game win , then the above script is running.
any help would be appreciated.
[SerializeField]
private Text gameTimeText;
[SerializeField]
private Text gameBestTimeText;
public static float timer;
private void Update()
{
timer += Time.deltaTime;
int minutes = Mathf.FloorToInt(timer / 60F);
int seconds = Mathf.FloorToInt(timer - minutes * 60);
gameTimeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
if (timer > PlayerPrefs.GetFloat("BestScore"))
{
PlayerPrefs.SetFloat("BestScore", timer);
}
//show the high score
gameBestTimeText.text = ""+((int)PlayerPrefs.GetFloat("BestScore"));
moneyAmountText.text = GlobalValues.money.ToString();
}
this is working but it does not show like minutes and seconds. how to fix the time format for best time ui text?
private void Update()
{
timer += Time.deltaTime;
int minutes = Mathf.FloorToInt(timer / 60F);
int seconds = Mathf.FloorToInt(timer - minutes * 60);
gameTimeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
if (timer > PlayerPrefs.GetFloat("BestScore"))
{
PlayerPrefs.SetFloat("BestScore", timer);
}
//show the high score
TimeSpan bestGametTime = TimeSpan.FromSeconds(PlayerPrefs.GetFloat("BestScore"));
gameBestTimeText.text = bestGametTime.Minutes + " : " + bestGametTime.Seconds;
moneyAmountText.text = GlobalValues.money.ToString();
}
this is now working but the problem is i need to save the best time in each game level as the lowest time when user wins the game. but now only the longest time is saved and showed. how can i fix that ?
Sphinks
February 23, 2021, 12:06pm
4
you check in your if on line 10, if your time is greater then the best score and if it is you set it has new best score. i think you have to check, if the time(r) is smaller then the current best time:
if (timer < PlayerPrefs.GetFloat("BestScore"))
{
PlayerPrefs.SetFloat("BestScore", timer);
}
1 Like
Sphinks:
you check in your if on line 10, if your time is greater then the best score and if it is you set it has new best score. i think you have to check, if the time(r) is smaller then the current best time:
if (timer < PlayerPrefs.GetFloat("BestScore"))
{
PlayerPrefs.SetFloat("BestScore", timer);
}
this is the point!
so the very first time game is running , actually there is not a best game time. i did like this for that i start method
[SerializeField]
private Text gameTimeText;
[SerializeField]
private Text gameBestTimeText;
public static float timer;
private float gameBestTime;
private void Start()
{
gameBestTime = PlayerPrefs.GetFloat("BestScore", 0);
}
private void Update()
{
timer += Time.deltaTime;
int minutes = Mathf.FloorToInt(timer / 60F);
int seconds = Mathf.FloorToInt(timer - minutes * 60);
gameTimeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
if (timer > PlayerPrefs.GetFloat("BestScore"))
{
PlayerPrefs.SetFloat("BestScore", timer);
}
//show the high score
TimeSpan bestGametTime = TimeSpan.FromSeconds(PlayerPrefs.GetFloat("BestScore"));
gameBestTimeText.text = bestGametTime.Minutes + " : " + bestGametTime.Seconds;
gameBestTimeText.color = Color.yellow;
moneyAmountText.text = GlobalValues.money.ToString();
}
and now only on game win condition , i need a comparision if best time is the lowest amongst , then yes set and save it.
how can i do it ? i am confused. please help ^^
Sphinks
February 23, 2021, 12:29pm
6
for that you need a flag which you set, if the game was finished/won:
private bool wonGame;
private void Update()
{
// your current timer code
if (wonGame)
{
if (timer > PlayerPrefs.GetFloat("BestScore")
{
PlayerPrefs.SetFloat("BestScore", timer);
}
}
}
to set the value of the flag to true, you need a method or something in your Upload() that is called/triggered as soon as the game is finished
1 Like
Sphinks:
for that you need a flag which you set, if the game was finished/won:
private bool wonGame;
private void Update()
{
// your current timer code
if (wonGame)
{
if (timer > PlayerPrefs.GetFloat("BestScore")
{
PlayerPrefs.SetFloat("BestScore", timer);
}
}
}
to set the value of the flag to true, you need a method or something in your Upload() that is called/triggered as soon as the game is finished
so still (timer > or (timer < ???
because i need the lowest time which user won the game level to be registerd.
how really do that?
Sphinks
February 23, 2021, 1:19pm
8
ah yes sure still < sry, didn´t copy it, but typed it again. if you want the lower one it´s always <
1 Like
this is not working and each time level is finished , best time is zero. why?
using UnityEngine;
using System;
using UnityEngine.UI;
public class GameLevelInfo : MonoBehaviour
{
[SerializeField]
private Text moneyAmountText;
[SerializeField]
private Text gameTimeText;
[SerializeField]
private Text gameBestTimeText;
public static float timer;
private float gameBestTime;
// set it true when game win is done.
public static bool wonGame = false;
private void Start()
{
gameBestTime = PlayerPrefs.GetFloat("BestScore", 0);
}
private void Update()
{
timer += Time.deltaTime;
int minutes = Mathf.FloorToInt(timer / 60F);
int seconds = Mathf.FloorToInt(timer - minutes * 60);
gameTimeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
if (wonGame)
{
if (timer < PlayerPrefs.GetFloat("BestScore"))
{
PlayerPrefs.SetFloat("BestScore", timer);
}
}
TimeSpan bestGametTime = TimeSpan.FromSeconds(PlayerPrefs.GetFloat("BestScore"));
gameBestTimeText.text = bestGametTime.Minutes + " : " + bestGametTime.Seconds;
gameBestTimeText.color = Color.yellow;
moneyAmountText.text = GlobalValues.money.ToString();
}
}
using UnityEngine;
public class FinishLevel : MonoBehaviour
{
[SerializeField]
private int coinsAmount;
[SerializeField]
private int coinsToTake;
[SerializeField]
private GameObject collectCoinsPanel;
[SerializeField]
private GameObject levelWinPanel;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
if (coinsAmount >= coinsToTake)
{
levelWinPanel.SetActive(true);
GameLevelInfo.wonGame = true;
Time.timeScale = 0f;
}
else
{
collectCoinsPanel.SetActive(true);
GameLevelInfo.wonGame = true;
Time.timeScale = 0f;
}
}
}
}
Sphinks
February 23, 2021, 1:43pm
10
what exactly does not work ?
only the score value in your GameLevelInfo or your FinishLevel script as well ?
Debug it or put some debug logging in it to see the values on the different places.
Is the if (wonGame) passed ?
Is the value of “timer” correct ?
Do you really need the field “gameBestTime” you set it to 0 in the Start method, but never use it.
1 Like
Sphinks:
what exactly does not work ?
only the score value in your GameLevelInfo or your FinishLevel script as well ?
Debug it or put some debug logging in it to see the values on the different places.
Is the if (wonGame) passed ?
Is the value of “timer” correct ?
Do you really need the field “gameBestTime” you set it to 0 in the Start method, but never use it.
Do you really need the field “gameBestTime” you set it to 0 in the Start method, but never use it.
it is because the first time game runs , the initial value for that to be defined as 0. or i am wrong with that?
Sphinks:
what exactly does not work ?
only the score value in your GameLevelInfo or your FinishLevel script as well ?
Debug it or put some debug logging in it to see the values on the different places.
Is the if (wonGame) passed ?
Is the value of “timer” correct ?
Do you really need the field “gameBestTime” you set it to 0 in the Start method, but never use it.
on FinishLevel script with debug.log the value for coinsAmount is always equal to 0.
this is the problem. then i assigned the coins value to that in start method. again it does not work.
private void Start()
{
coinsAmount = GlobalValues.money;
}
i dont know what to do now
Anytime you think the above thought, this should be your instantaneously-next thought:
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run?
what are the values of the variables involved? Are they initialized?
Knowing this information will help you reason about the behavior you are seeing.
1 Like
Kurt-Dekker:
Anytime you think the above thought, this should be your instantaneously-next thought:
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run?
what are the values of the variables involved? Are they initialized?
Knowing this information will help you reason about the behavior you are seeing.
i did debug.log but as i said above here coinsAmount is always 0. but i have already took some coins. and i dont expect to find it as 0. why coinsAmount does not become as much as coins that are taken ?
if (coinsAmount >= coinsToTake)
{
levelWinPanel.SetActive(true);
GameLevelInfo.wonGame = true;
Time.timeScale = 0f;
}
No, no you didn’t. Until you literally print EVERYTHING you are not finished.
the coins before
the amount you are considering adding
the coins after
the coins where you try to use them next time
etc etc etc.
2 Likes
Sphinks:
what exactly does not work ?
only the score value in your GameLevelInfo or your FinishLevel script as well ?
Debug it or put some debug logging in it to see the values on the different places.
Is the if (wonGame) passed ?
Is the value of “timer” correct ?
Do you really need the field “gameBestTime” you set it to 0 in the Start method, but never use it.
so after searching in the code here it is :
the value of “timer” is correct when if (timer > PlayerPrefs.GetFloat(“BestScore”)) but in this case the highest time is always saved and displayed. rather i need to see the lowest time as game level time.
the value of “timer” is not correct when if (timer < PlayerPrefs.GetFloat(“BestScore”)) either.
how to fix that? how to give the comparison the correct amount for PlayerPrefs.GetFloat(“BestScore”?
If you finish something in one second, is that a better time than zero seconds?
It’s not, so that’s probably why the zero is not being replaced.
This is the logic you want:
if ((best time does NOT exist) OR (current time is better than (less than) best time))
{
replace best time with current time
}
PlayerPrefs.HasKey() can tell you if anything exists for that key.
And obviously if you don’t HAVE a best time, don’t show zero because that’s confusing. Show no best time at all.
2 Likes
Kurt-Dekker:
If you finish something in one second, is that a better time than zero seconds?
It’s not, so that’s probably why the zero is not being replaced.
This is the logic you want:
if ((best time does NOT exist) OR (current time is better than (less than) best time))
{
replace best time with current time
}
PlayerPrefs.HasKey() can tell you if anything exists for that key.
And obviously if you don’t HAVE a best time, don’t show zero because that’s confusing. Show no best time at all.
this is excactly what i need . let me see how it come in true with codes ^^ . thanks.
You’re welcome! I recommend you wrap all those PlayerPrefs calls up somewhere you don’t have to keep retyping “BestScores” and whatnot.
Here’s an example of simple persistent loading/saving values using PlayerPrefs:
Useful for a relatively small number of simple values.
You could add to that a method called “HaveBestScore()” and then if you decide to change how best scores are stored in the future, none of your game changes, just this one module.
2 Likes
Kurt-Dekker:
You’re welcome! I recommend you wrap all those PlayerPrefs calls up somewhere you don’t have to keep retyping “BestScores” and whatnot.
Here’s an example of simple persistent loading/saving values using PlayerPrefs:
Simple Unity3D Persistent SETTINGS - Pastebin.com
Useful for a relatively small number of simple values.
You could add to that a method called “HaveBestScore()” and then if you decide to change how best scores are stored in the future, none of your game changes, just this one module.
i cannot post my question. but here it is :
when i go to another scene and come back best time is 0.
and also first time best time is 0 but other time it is a very small number. what is wrong ? why still not working?
0.02
UnityEngine.Debug:Log(Object)
GameLevelInfo:Start() (at Assets/Scripts/GameLevelInfo.cs:22)
private void Update()
{
timer += Time.deltaTime;
int minutes = Mathf.FloorToInt(timer / 60F);
int seconds = Mathf.FloorToInt(timer - minutes * 60);
gameTimeText.text = string.Format("{0:0}:{1:00}", minutes, seconds);
TimeSpan bestGametTime = TimeSpan.FromSeconds(PlayerPrefs.GetFloat("BestScore"));
gameBestTimeText.text = bestGametTime.Minutes + " : " + bestGametTime.Seconds;
gameBestTimeText.color = Color.yellow;
if (wonGame)
{
if (PlayerPrefs.GetFloat("BestScore") == 0 || timer < PlayerPrefs.GetFloat("BestScore"))
{
Debug.Log("here");
PlayerPrefs.SetFloat("BestScore", timer);
PlayerPrefs.Save();
}
}
moneyAmountText.text = GlobalValues.money.ToString();
}
scene change:
public void LoadLevel(int sceneIndex)
{
StartCoroutine(LoadAsynchronously(sceneIndex));
GameLevelInfo.timer = 0;
}