Ok, this is what I came up with:
using System.Linq;
using System;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class HighScoreBoard : MonoBehaviour //Placed on the ScoreBoard Panel
{
HighScoreBoardSerializer board = new HighScoreBoardSerializer();
public SaveHighScores highScores; //Drag in EventSystem into inspector
Transform scores;
public void StartGame() //Called when starting a new game, loads saved data if available, otherwise creates the following
{
scores = transform.GetChild(1); //Set the second child, Scores Empty Object, to scores
board = highScores.LoadGameData();
if(board.HighScoreList.Count == 0) //New Game, an example of how to add scores to the High Score List
{
board.HighScoreList.Add(new HighScore {
Name = "Player01", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player02", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player03", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player04", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player05", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player06", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player07", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player08", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player09", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
board.HighScoreList.Add(new HighScore {
Name = "Player10", Time = 0.0f, Incorrect = 0, dateTime = DateTime.Now.ToString() });
}
}
public void SaveGame() //Called on completion of a game
{
highScores.SaveGameData(board);
}
public void DisplayScoreBoard() //Does what it says
{
board.HighScoreList = board.HighScoreList.OrderBy
(
i => i.Incorrect //First sort by Incorrect guesses
).ThenBy
(
t => t.Time //Second, sort by Time elapsed
).ThenBy
(
p => p.dateTime //Finally, sort by Date and Time completed
).ToList();
gameObject.SetActive(true);
int count = 0;
foreach (HighScore score in board.HighScoreList)
{
scores.GetChild(count).GetComponent<Text>().text =
(count + 1) + ": " + score.Name + " - " + score.Time + " - " + score.Incorrect + " - " + score.dateTime;
count++;
if(count > 9)
{
break; //Only display the top 10 scores
}
}
}
public void CloseScoreBoard() //Close Button on the ScoreBoard
{
gameObject.SetActive(false);
}
}
[Serializable]
public class HighScoreBoardSerializer
{
public List<HighScore> HighScoreList = new List<HighScore>();
}
[Serializable]
public class HighScore
{
public string Name;
public float Time;
public int Incorrect;
public string dateTime; //Added as a third check in case more than 1 player shares Incorrect and Time
}
A separate script for saving the data to file:
using UnityEngine;
using System.IO;
public class SaveHighScores : MonoBehaviour //Placed on the EventSystem
{
string GetSaveLocationPath() //Create a Path variable so we don't need to keep getting the path
{
string folder = Application.persistentDataPath;
string file = "Save.json";
string fullPath = Path.Combine(folder, file);
return fullPath;
}
public void SaveGameData(HighScoreBoardSerializer board)
{
string json = JsonUtility.ToJson(board); //Format data to json
string fullPath = GetSaveLocationPath();
if(File.Exists(fullPath))
{
Debug.Log("File Deleted");
File.Delete(fullPath); //Delete the file instead of adding to it
}
File.WriteAllText(fullPath, json);
}
public HighScoreBoardSerializer LoadGameData()
{
string fullPath = GetSaveLocationPath();
if(File.Exists(fullPath))
{
string jsonString = File.ReadAllText(fullPath);
Debug.Log("Game Loaded");
return JsonUtility.FromJson<HighScoreBoardSerializer>(jsonString);
}
else
{
Debug.Log("New Game");
return new HighScoreBoardSerializer();
}
}
}
and an example of the layout, this you will need to tweak to your needs but it shows how the Hierarchy was set up:
I’m sure there are more elegant ways of doing it but this works, feel free to ask about anything you may not understand.