Files
Inter-Face-Off/Assets/Scripts/ScoreTracker.cs
2026-01-27 09:47:11 +00:00

147 lines
4.6 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
using InterfaceOff.MainMenu;
using UnityEngine;
using UnityEngine.UI;
namespace InterfaceOff.WorldScene
{
[System.Serializable]
public struct PlayerScore
{
public string PlayerName;
public float Score;
}
[System.Serializable]
public struct PlayerScoreDump
{
public PlayerScore[] Scores;
}
public class ScoreTracker : MonoBehaviour
{
[field: SerializeField] private bool GameAngliaVersion { get; set; }
[field: SerializeField] private Text ScoreText { get; set; }
[field: SerializeField] private Text FinalScoreText { get; set; }
[field: SerializeField] private WindowSpawner Spawner { get; set; }
[field: SerializeField] private GameObject LeaderboardObject { get; set; }
[field: SerializeField] private GameObject LeaderboardEntryPrefab { get; set; }
[field: SerializeField] private InputField PlayerTextNameInput { get; set; }
[field: SerializeField] private Button IDRKWhatToCallThis { get; set; }
private static List<PlayerScore> PlayerScores { get; } = new();
private static ScoreTracker Instance { get; set; }
private string CurrentPlayerName { get; set; } = string.Empty;
private bool StoredCurrentScore = false;
private float Score;
#if UNITY_STANDALONE_WIN
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void OnStart()
{
string path = Path.Combine(Application.persistentDataPath, "scores.json");
if (File.Exists(path))
{
string json = File.ReadAllText(path);
PlayerScoreDump dmp = JsonUtility.FromJson<PlayerScoreDump>(json);
foreach (PlayerScore score in dmp.Scores)
{
PlayerScores.Add(score);
}
}
}
private void OnDestroy()
{
Debug.Log("Dumped scores");
PlayerScoreDump dmp = new();
dmp.Scores = PlayerScores.ToArray();
string json = JsonUtility.ToJson(dmp, prettyPrint: false);
File.WriteAllText(Path.Combine(Application.persistentDataPath, "scores.json"), contents: json);
}
#endif // UNITY_STANDALONE_WIN
public static float CurrentScore()
{
if (DebugUtils.IsNull(Instance))
{
return 0;
}
return Instance.Score;
}
private void RepaintLeaderboard()
{
foreach (Transform child in LeaderboardObject.transform)
{
Destroy(child.gameObject);
}
PlayerScore[] scores = PlayerScores
.OrderByDescending(playerScore => playerScore.Score)
.Take(10)
.ToArray();
for (int idx = 0; idx < scores.Length; idx++)
{
GameObject go = Instantiate(LeaderboardEntryPrefab, LeaderboardObject.transform);
RectTransform rect = go.GetComponent<RectTransform>();
Text entryText = go.GetComponent<Text>();
entryText.text = $"[{scores[idx].PlayerName}] - {scores[idx].Score:F1}";
rect.anchoredPosition = new Vector2(0, 220 - ((idx + 1) * 40));
}
}
private void Awake()
{
RepaintLeaderboard();
Instance = this;
}
private void Update()
{
if (Spawner.AutoSpawn)
{
StoredCurrentScore = false;
Score = Time.timeSinceLevelLoad * DifficultyManager.DifficultyEffect;
ScoreText.text = $"Score: {Score:F1}";
}
else
{
FinalScoreText.text = $"Your final score is: {Score:F1}";
ScoreText.text = null;
}
}
public void AddCurrentScoreToLeaderboard()
{
if (CurrentPlayerName != string.Empty && !StoredCurrentScore)
{
PlayerScore score = new();
score.PlayerName = CurrentPlayerName;
score.Score = CurrentScore();
StoredCurrentScore = true;
PlayerScores.Add(score);
RepaintLeaderboard();
PlayerTextNameInput.interactable = false;
IDRKWhatToCallThis.interactable = false;
}
}
public void SetPlayerName(string input) => CurrentPlayerName = input;
}
}