using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Unisave.Facades;
using Unisave.Facets;
using Unisave;
public class LeaderboardController : MonoBehaviour
{
// references to UI components,
// must be set up manually in the inspector window
public TextMeshProUGUI leftText;
public TextMeshProUGUI rightText;
public TMP_InputField nameField;
public Button submitButton;
// information about this level run
private float currentScore;
private string levelName;
// state that controls the UI
// (the snapshot is null while it's being downloaded)
private LeaderboardSnapshot snapshot = null;
private int? estimatedPosition = null;
private bool scoreWasSubmitted = false;
void Start()
{
submitButton.onClick.AddListener(SubmitScore);
}
// when the leaderboard dialog window is displayed
async void OnEnable()
{
// dummy code,
// pull the number from your score tracking script instead
currentScore = UnityEngine.Random.Range(0.0f, 1000.0f);
// dummy code,
// pull this from your level naming system
levelName = SceneManager.GetActiveScene().name;
// reset the UI state and re-render
snapshot = null;
estimatedPosition = null;
scoreWasSubmitted = false;
Render();
// download the leaderboard and re-render
snapshot = await this.CallFacet(
(LeaderboardFacet f) => f.DownloadSnapshot(
levelName
)
);
estimatedPosition = await this.CallFacet(
(LeaderboardFacet f) => f.EstimatePosition(
levelName,
currentScore
)
);
Render();
}
// when the submit button is clicked
async void SubmitScore()
{
// forget the old snapshot and download the new one
snapshot = null;
scoreWasSubmitted = true;
Render();
// submit the score and download the new snapshot
await this.CallFacet(
(LeaderboardFacet f) => f.SubmitScore(
levelName,
nameField.text,
currentScore
)
);
snapshot = await this.CallFacet(
(LeaderboardFacet f) => f.DownloadSnapshot(
levelName
)
);
Render();
}
///////////////////////
// UI Rendering code //
///////////////////////
// Updates the UI based on the state
void Render()
{
if (snapshot == null || estimatedPosition === null)
{
RenderLoading();
RenderSubmitUI(isVisible: false);
}
else
{
RenderLeaderboard();
RenderSubmitUI(isVisible: !scoreWasSubmitted);
}
}
void RenderLoading()
{
leftText.text = "Name\n\nLoading leaderboard...";
rightText.text = "Score";
}
void RenderLeaderboard()
{
// get a copy of the top 5 records
// (the server sent us top 100 records, we only show top 5)
List<(string, float)> renderedRecords = snapshot.topRecords
.Take(5)
.ToList();
// if the leaderboard is too empty, add dummy records
// to make sure our table always has 5 rows
while (renderedRecords.Count < 5)
renderedRecords.Add(("---", 0.0f));
// render the table header
leftText.text = "Name\n";
rightText.text = "Score\n";
// render table rows
int i = 1;
foreach ((string name, float score) in renderedRecords)
{
// 1. Alice 123
// 2. Peter 123
leftText.text += i + ". " + name + "\n";
rightText.text += Mathf.RoundToInt(score) + "\n";
i += 1;
}
// show the estimated position
leftText.text += "\n" + estimatedPosition.Value + ". You";
rightText.text += "\n" + Mathf.RoundToInt(currentScore) + "\n";
}
void RenderSubmitUI(bool isVisible)
{
nameField.gameObject.SetActive(isVisible);
submitButton.gameObject.SetActive(isVisible);
}
}