Prerequisites
- Unity 2021 LTS or newer
- A LightLeaderboard account, game, and API key
UnityEngine.Networking— included in Unity, no install needed
iOS / Android:
UnityWebRequest works on all platforms Unity supports.
No extra networking configuration required.Step 1 — Add the Data Classes
Create ScorePayload.cs in your project. Unity's JsonUtility requires [Serializable] classes — no Newtonsoft needed.
// ScorePayload.cs — add to your project
using System;
[Serializable]
public class ScorePayload
{
public int score;
public string playerRefId;
public string playerName;
public string submissionId;
}
[Serializable]
public class ScoreResponse
{
public int id;
public int rank;
public int score;
public string playerName;
}
[Serializable]
public class LeaderboardEntry
{
public int rank;
public string playerName;
public int score;
}
[Serializable]
public class LeaderboardResponse
{
public LeaderboardEntry[] entries;
}Step 2 — Submit a Score
Attach LeaderboardManager to a persistent GameObject (e.g. your GameManager). Call SubmitScore() from any other script.
// LeaderboardManager.cs — attach to any GameObject
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class LeaderboardManager : MonoBehaviour
{
const string ApiUrl = "https://yourapp.com/api/v1/games/my_game";
const string ApiKey = "YOUR_API_KEY";
public void SubmitScore(int score, string playerId, string playerName)
=> StartCoroutine(SubmitScoreCoroutine(score, playerId, playerName));
IEnumerator SubmitScoreCoroutine(int score, string playerId, string playerName)
{
var payload = new ScorePayload {
score = score,
playerRefId = playerId,
playerName = playerName,
submissionId = System.Guid.NewGuid().ToString(),
};
byte[] body = System.Text.Encoding.UTF8
.GetBytes(JsonUtility.ToJson(payload));
using var req = new UnityWebRequest(ApiUrl + "/scores", "POST");
req.uploadHandler = new UploadHandlerRaw(body);
req.downloadHandler = new DownloadHandlerBuffer();
req.SetRequestHeader("Authorization", "Bearer " + ApiKey);
req.SetRequestHeader("Content-Type", "application/json");
yield return req.SendWebRequest();
if (req.result == UnityWebRequest.Result.Success)
{
var res = JsonUtility.FromJson<ScoreResponse>(req.downloadHandler.text);
Debug.Log($"Submitted! Rank: #{res.rank}");
// update your UI here
}
}
}Step 3 — Fetch the Leaderboard
Add GetLeaderboard() to the same manager. Call it from your leaderboard
UI screen's Start() or OnEnable().
// Add to LeaderboardManager.cs
public void GetLeaderboard(int limit = 10)
=> StartCoroutine(GetLeaderboardCoroutine(limit));
IEnumerator GetLeaderboardCoroutine(int limit)
{
using var req = UnityWebRequest.Get(
$"{ApiUrl}/leaderboard?limit={limit}");
req.SetRequestHeader("Authorization", "Bearer " + ApiKey);
yield return req.SendWebRequest();
if (req.result == UnityWebRequest.Result.Success)
{
var res = JsonUtility.FromJson<LeaderboardResponse>(
req.downloadHandler.text);
foreach (var e in res.entries)
Debug.Log($"#{e.rank} {e.playerName} {e.score}");
// populate your UI Text or TMP components
}
}Tips
- Store
ApiKeyin aScriptableObjector Unity'sPlayerPrefsrather than hardcoding it if you need runtime configuration. System.Guid.NewGuid().ToString()is the cleanest way to generate a uniquesubmissionIdin Unity.- For TMP (TextMeshPro) leaderboards, set
rankText.text = $"#{e.rank}"inside the loop — works identically toDebug.Log. - If targeting WebGL, replace
UnityWebRequestwith a JS interop call — or route through your own backend since WebGL CORS restrictions can block direct API calls depending on browser policy.