So i really am stumped… With the code below the score shows the time that the timer is stopped… I.e. the end of the level… So if the level takes 1 min and 20 seconds to complete than the Time finished shows 1 min 20 secs…
Then for some reason the Best time also shows this same score… Then when i replay the level the time completed goes back to 0 as intended, but so does the best score… I need the best score to stay at the the previous time completed and only change if the new time is less that the previous time… I suck royaly at math so maybe my calculations are all jagged up… Maybe its my data save thats also wrong i dunno… I completely started over and made a simple scene with two buttons, start timer and stop. and made two number fields that display score and best score… and the timer text…
TimerScore Script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TimerScore : MonoBehaviour {
public Text timerText;
public Text score;
public Text best;
public float startTime;
public float stopTime;
public bool isStarted;
// Use this for initialization
void Start ()
{
//Game.current._highScore = 999;
best.text = "" + Mathf.Round(Game.current._highScore);
SaveLoad.LoadGame();
}
public void StartThis()
{
startTime = 0;
isStarted = true;
}
public void StopThis()
{
isStarted = false;
stopTime = Time.deltaTime - startTime;
startTime += Time.deltaTime;
if(startTime > stopTime)
{
Debug.Log("Setting best to starttime");
Game.current._highScore = startTime;
best.text = "" + Mathf.Round(Game.current._highScore);
Game.current.newTime = true;
SaveLoad.SaveGame();
}
else if (startTime < stopTime)
{
Debug.Log("Setting best to stoptime");
Game.current._highScore = stopTime;
best.text = "" + Mathf.Round(Game.current._highScore);
Game.current.newTime = false;
SaveLoad.SaveGame();
}
}
// Update is called once per frame
void Update () {
if (isStarted)
{
startTime += Time.deltaTime;
float minutes = startTime / 60;
float seconds = startTime % 60;
timerText.text = string.Format("{0:00} : {1:00}", minutes, seconds);
score.text = "" + Mathf.Round(startTime);
}
}
}
My Two Scripts for saving data…
Game Script…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Game
{
public static Game current = new Game();
public float _highScore;
public float highScore;
public bool newTime;
}
And my SaveLoad Script…
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoad
{
public static void SaveGame()
{
BinaryFormatter bf = new BinaryFormatter();
if (File.Exists(Application.persistentDataPath + "/SavedGame.dat"))
{
FileStream file = File.Open(Application.persistentDataPath + "/SavedGame.dat", FileMode.Open);
Game game = new Game();
game.highScore = Game.current.highScore;
game._highScore = Game.current._highScore;
game.newTime = Game.current.newTime;
bf.Serialize(file, Game.current);
file.Close();
}
else
{
FileStream file = File.Create(Application.persistentDataPath + "/SavedGame.dat");
Game game = new Game();
game.highScore = Game.current.highScore;
game._highScore = Game.current._highScore;
game.newTime = Game.current.newTime;
bf.Serialize(file, Game.current);
}
}
public static void LoadGame()
{
if (File.Exists(Application.persistentDataPath + "/SavedGame.dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/SavedGame.dat", FileMode.Open);
Game game = (Game)bf.Deserialize(file);
file.Close();
Game.current.highScore = game.highScore;
Game.current.highScore = game._highScore;
Game.current.newTime = game.newTime;
Debug.Log("Loaded The File");
}
else
{
Debug.Log("File Does Not Exist");
}
}
}
float startTime = Time.time;
// later on, when finishing that round..
float duration = Time.time - startTime;
if(duration < bestTime) {
// adjust best time + text field, etc..
}
Well, if you’re restarting in the same scene, just make sure you leave the best score text unchanged.
if you’re doing it from a scene change, then you’d have to carry the variable over , with:
dontdestroyonload
playerprefs
static variable
or something else that keeps the value around
Im using serialized data. I save the float of the bets time. I also tried saving the best time as an int and just add the best time to it if its less than the previous.
Yeah i can do a simple player pref but we both know thats crude. Plus people tend to hack a game any chance they can. Thats why i wanted to use serialization. I used it before for gold amounts but not for keeping a time based score.
Ya, but all i was saying was just do a simple test. Make sure that’s not the issue. Then check the next thing (maybe what you assign to the text object)… step by step and track down the bug.
I wasn’t suggesting you move to player prefs. I figured you had your reasons for the way you were doing it.
Ive been looking. And to be honest i am stuck. I dont think ive spent so much time on a script as i have on this. It seems so simple yet i’m puzzled. I’ve used Logs where needed. Ive tracked that the values are being updates, ive tracked that the data is indeed being saved and loaded. Thanks for the help though buddy.
The text is updating fine. I can get the score and best score now. I** The problem is saving the value of the best score versus the current score and then saving it to the serialization data… Then having that high score to show on restart.
It may be sloppy but i finally got it!!! Here is the final scripts if anyone wants them. Enjoy!
TimerScore Script in an empty gameobject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TimerScore : MonoBehaviour
{
public static TimerScore TC;
public Text timerText;
public Text score;
public Text best;
public bool isStarted;
public float _startTime;
int testNum;
public void Awake()
{
SaveLoad.LoadGame();
}
void Start()
{
best.text = "" + Game.current._highscore;
TC = this;
}
void Update()
{
if (isStarted)
{
_startTime += Time.deltaTime;
timerText.text = "" + Mathf.Round(_startTime);
}
}
public void StartThis()
{
isStarted = true;
_startTime = 0;
score.text = "" + 0;
Game.current.firstTime = false;
best.text = "" + Game.current._highscore;
}
public void StopThis()
{
isStarted = false;
score.text = "" + Mathf.Round(_startTime);
Game.current.score = (int)Mathf.Round(TC.GetComponent<TimerScore>()._startTime);
Game.current.firstTime = false;
SaveLoad.SaveGame();
if(Game.current.score < Game.current._highscore)
{
Debug.Log("Updating Score to _starttime");
best.text = "" + Mathf.Round(_startTime);
Game.current._highscore = (int)Mathf.Round(TC.GetComponent<TimerScore>()._startTime);
SaveLoad.SaveGame();
}
else {
Debug.Log("Leaveing text to be _highscore");
best.text = "" + Mathf.Round(Game.current._highscore);
SaveLoad.SaveGame();
}
}
}
Game Script for binary format…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Game
{
public static Game current = new Game();
public float score;
public int _highscore;
public bool firstTime;
}
And the SaveLoad Script for saving and loading items in Game script…
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoad
{
public static void SaveGame()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/SaveGame.dat");
Game game = new Game();
game.score = Game.current.score;
game._highscore = Game.current._highscore;
game.firstTime = Game.current.firstTime;
bf.Serialize(file, Game.current);
file.Close();
Debug.Log("Saved The File");
}
public static void LoadGame()
{
if (File.Exists(Application.persistentDataPath + "/SaveGame.dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/SaveGame.dat", FileMode.Open);
Game game = (Game)bf.Deserialize(file);
file.Close();
Game.current.score = game.score;
Game.current._highscore = game._highscore;
Game.current.firstTime = game.firstTime;
Debug.Log("Loaded The File");
}
else
{
Debug.Log("File Does Not Exist");
}
}
}