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 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(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(); Text entryText = go.GetComponent(); 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; } }