Skip to content

Instantly share code, notes, and snippets.

@uni-bbl
Last active March 21, 2018 07:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uni-bbl/15ff30f49bf7dd19d44b to your computer and use it in GitHub Desktop.
Save uni-bbl/15ff30f49bf7dd19d44b to your computer and use it in GitHub Desktop.
Basic integration for GameSparks with Unity3D
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//
using GameSparks.Api;
using GameSparks.Api.Requests;
using GameSparks.Api.Responses;
using GameSparks.Core;
/**
* GameSparks API integration
* doc: http://tinyurl.com/hprfxm3
*/
public class GameSparksApi: MonoBehaviour {
[Header("Authentication")]
public string playerNamePrefsKey = "Player Name";
public string playerNameDefault = "Anonymous";
public int maxLengthOfPlayerName = 16;
[Header("Leaderboard")]
[Tooltip("Match to leaderboard id in admin")]
public string leaderboardId = "HIGH_SCORE";
[Tooltip("Match to the attribute id in admin")]
public string scoreAttributeId = "SCORE";
[Tooltip("Match to the event key in admin ")]
public string scoreEventKey = "SUBMIT_SCORE";
public int leaderboardEntryCount = 20;
public bool fetchPlayerRankAndScoreAfterAuthenticating = false;
[Header("Debug")]
public bool log = false;
// static fields
public static bool authenticated = false;
public static string playerId = null;
public static int errorCount = 0;
public static int maxErrors = 100;
public static int playerRank = 0;
public static int playerScore = 0;
public static string formattedLeaderboard;
// private fields
private const string rankAttributeId = "rank";
private static GameSparksApi instance = null;
// PUBLIC -------------------------------------------------------
/**
* Call this to submit an analytics request.
* Tokens denote milestones or tasks defined by you.
* Keep tokens short and descriptive as they appear in your
* analytics report.
*/
public void Analytics(string token){
if (!authenticated) {
Debug.LogWarning ("Authenticate before sending API requests");
return;
}
try {
new AnalyticsRequest ().SetKey (token).Send ((response) => {
if (!response.HasErrors){
Debug.Log ("Analytics : [" + token + "] sent successfully");
}else{
Debug.LogWarning ("Analytics : [" + token + "]: error(s) in response");
}
});
} catch (System.Exception ex) {
Debug.LogError ("Error while sending analytics request: " + ex);
}
}
/**
* If this returns true we are ready to send other requests such
* as submit a score or an analytics request.
*/
public bool IsAuthenticated(){
return !string.IsNullOrEmpty (playerId);
}
/**
* Call this to submit the player's score.
*/
public void SubmitScore(int scoreValue){
string attributeValue = scoreValue.ToString ();
new LogEventRequest().
SetEventKey(scoreEventKey).SetEventAttribute(scoreAttributeId, attributeValue).Send((response) => {
if (!response.HasErrors) {
Log("Score posted successfully");
} else {
Log("Error posting score");
}
});
}
/**
* Call this to fetch the local player's rank and score.
* You will not receive a callback. Updated values are assigned
* to 'playerRank' and 'playerScore'.
* Customise this if you want to handle the callback instead.
*/
public void FetchPlayerRankAndScore(){
Log ("Fetch player rank and score");
List<string> lbs = new List<string> ();
lbs.Add ( leaderboardId );
new LeaderboardsEntriesRequest()
.SetPlayer (playerId)
.SetLeaderboards(lbs)
.Send((response) => {
if(!response.HasErrors){
try{
Log("Got player data for "+playerId);
Log (response.JSONString+" <> "+response.GetType ());
string json = response.JSONString;
JSONObject data = new JSONObject(json);
playerRank = (int) data[leaderboardId][0][rankAttributeId].n;
playerScore = (int) data[leaderboardId][0][scoreAttributeId].n;
}catch(System.Exception ex){
Log ("Unable to parse response: "+ex);
}
}else{
Log("Error retrieving player data");
}
});
}
/**
* Call this to fetch leaderboards.
* This does crude formatting of output in a single string,
* so you may want to customise.
* You will not receive a callback. A formatted leaderboard
* will be assigned to 'lbtext' so the recommended approach is to
* update a text component to display this.
*/
public void FetchLeaderboard(){
string lbtext = "";
new LeaderboardDataRequest().
SetLeaderboardShortCode(leaderboardId).
SetEntryCount(leaderboardEntryCount).Send((response) => {
if (!response.HasErrors) {
Log("Found leaderboard data");
foreach(GameSparks.Api.Responses.LeaderboardDataResponse._LeaderboardData entry in response.Data) {
int rank = (int) entry.Rank;
string playerName = entry.UserName;
if(playerName==null || playerName.Length==0)playerName="???";
string score = entry.JSONData[scoreAttributeId].ToString();
if(int.Parse(score)>0){
string trimmed = playerName;
if( trimmed.Length > maxLengthOfPlayerName )trimmed =
playerName.Substring(0, maxLengthOfPlayerName)+"...";
lbtext += "#" + rank + " " + trimmed +" ("+score+")\n";
}
Log("Rank:" + rank + " Name:" + playerName + " \n Score:" + score);
}
formattedLeaderboard = lbtext;
} else {
Log("Error retrieving leaderboard data");
}
});
}
/**
* Call this to submit an updated nickname to the back-end service
*/
public void SubmitDisplayName(string name){
if (name.Length > maxLengthOfPlayerName) name = name.Substring (0, maxLengthOfPlayerName);
new GameSparks.Api.Requests.ChangeUserDetailsRequest ().SetDisplayName (name).Send ((response) => {
if(!response.HasErrors)Debug.Log ("display name successfully updated");
});
}
// IMPLEMENTATION -----------------------------------------------------------
void Awake() {
if (instance == null) {
instance = this;
DontDestroyOnLoad (this.gameObject);
} else {
Destroy (this.gameObject);
}
StartAPI ();
}
void StartAPI(){
Log ("Start API");
GS.GameSparksAvailable = (available) => {
if(available) {
Log ("Connected");
Authenticate();
} else {
Log ("Not connected");
}
};
}
void Authenticate(){
string displayName=PlayerPrefs.GetString ( playerNamePrefsKey, playerNameDefault );
new GameSparks.Api.Requests.DeviceAuthenticationRequest().SetDisplayName(displayName).Send((response) => {
if (!response.HasErrors) {
Log("Device authenticated");
authenticated = true;
Log ("Got player id: "+response.UserId);
playerId = response.UserId;
if (fetchPlayerRankAndScoreAfterAuthenticating) FetchPlayerRankAndScore ();
} else {
Log("Error authenticating device");
}
});
}
static void Log(object obj){
if (!instance.log) return;
Debug.Log ("GameSparks: "+obj);
}
}
using UnityEngine;
/**
* Illustrates how to provide a 'hard link' to seamlessly access the
* GameSparksAPI singleton, meaning this will work even after switching
* to another scene.
*/
public class Analytics : MonoBehaviour {
public void Send(string token){
GameSparksApi api = FindObjectOfType<GameSparksApi> ();
api.Analytics (token);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment