Integrate Triumph scoring in your game. Estimated Time: 10 minutes.
Start Game
Triumph needs to start an instance of your game when a match is initiated. We will call a function TriumphGameDidStart when we would like a game to start. You will implement this function with logic to start an instance of your game.
Implement the TriumphUnityNativeMethods component of the TriumphAPI prefab.
using UnityEngine;
using TriumphSDK;
public class TriumphUnityNativeMethods: MonoBehaviour, ITriumphUnityNativeMethods {
/*
* TODO: implement this method, which we will call when.
* a user has initiated a tournament.
*/
public void TriumphStartedGame()
{
StartYourGame();
}
// MARK: -- Optional
/*
* If you provided `hasTutorial` flag within configuration options,
* this method will be called when Triumph wants to show the tutorial.
* You can start a fullscreen video with your gameplay mechanics
* or launch a playable game with hints to onboard new players.
*/
public void TriumphRequestsTutorial()
{
StartYourTutorial();
}
/*
* The below methods can be used for logging purposes,
* left blank, or whatever you'd like.
* Please leave them in the code (even if blank).
*/
// We call this when the triumph SDK is dismissed.
public void TriumphDidDismiss()
{
}
// Called when the SDK presents
public void TriumphDidPresent()
{
}
// Called right before the SDK dismisses
public void TriumphWillDismiss()
{
}
// Called right before the SDK presents
public void TriumphWillPresent()
{
}
}
When you finished presenting tutorial to a new player, do not forget to present Triumph again:
using TriumphSDK;
public class TutorialScene : MonoBehaviour {
// Called when your tutorial has finished playing
public void TutorialFinished() {
Triumph.present()
}
}
Navigate to the file where your gameplay lifecycle is managed, i.e. where you have the ability to start and end games.
Set Triumph.delegate = self in the viewDidLoad function of this class, and conform to TriumphDelegate. This allows us to pass data between your game and Triumph.
import TriumphSDK
class YourGameViewController: TriumphDelegate {
// Allows Triumph to communicate with your game
func viewDidLoad() {
Triumph.delegate = self
}
// Required: reset and start your game here.
func triumphStartedGame() {
startYourGame()
}
// MARK: -- Optional
/*
* If you provided `hasTutorial` flag within configuration options,
* this method will be called when Triumph wants to show the tutorial.
* You can start a fullscreen video with your gameplay mechanics
* or launch a playable game with hints to onboard new players.
*/
func triumphRequestsTutorial() {
startYourTutorial()
}
/*
* The below methods can be used for logging purposes,
* left blank, or whatever you'd like.
* Please leave them in the code (even if blank).
*/
// Tells you that Triumph will present
func triumphWillPresent() {}
// Tells you that Triumph did present
func triumphDidPresent() {}
// Tells you that Triumph will dismiss
func triumphWillDismiss() {}
// Tells you that Triumph was dismiss
func triumphDidDismiss() {}
}
When you finished presenting tutorial to a new player, do not forget to present Triumph again:
class YourTutorialViewController {
// Called when your tutorial has finished playing
func tutorialFinished() {
Triumph.present()
}
}
These method implementations will be called on our end when appropriate. Do not call these methods anywhere yourself.
Game pause/resume
(Optional) If you have pausing functionality in your game, please add the following Triumph functions. This allows us to optimize replay recordings of your game.
using TriumphSDK;
public class GameScene : MonoBehaviour {
// Your pause game business logic
void Pause()
{
// Add this Triumph function
Triumph.GamePaused();
}
// Your resume game business logic
void Resume()
{
// Add this Triumph function
Triumph.GameResumed();
}
}
import TriumphSDK
class YourGameViewController {
// Your pause game business logic
func pause() {
// Add this Triumph function
Triumph.gamePaused()
}
// Your resume game business logic
func resume() {
// Add this Triumph function
Triumph.gameResume()
}
}
Report Score
Triumph needs to record scores from your game. There are two functions that you will call:
updateScore should be called whenever the score of your game changes, passing the current score as a parameter. This allows us to keep intermediate scores stored in the state of our SDK, so if a game crashes before completion, we have something for the user's score rather than simply reporting 0.
gameOver should be called when a game ends, passing the final score of the game as a parameter. This will submit the final score and resummon Triumph's UI.
using TriumphSDK;
public class GameScene : MonoBehaviour {
public int score = 0;
// Whenever a score changes, call updateScore with the current score.
// @Params: score: double
public void IncreaseScore(int increment)
{
score += increment;
Triumph.UpdateScore(score: score);
}
// Your game logic when the user loses and the game ends
// @Params: score: double
public void EndGame(int finalScore)
{
Triumph.GameOver(score: finalScore);
}
}
import TriumphSDK
class YourGameViewController {
// Whenever a score changes, call updateScore with the current score.
// Doing this on a didSet ensures we call this on every score update,
// although your implementation may differ
// @Params: score: Double
var gameScore: Double? {
didSet {
Triumph.updateScore(score: gameScore)
}
}
// User got a headshot! (or whatever your game logic is)
func headShot() {
let HEADSHOT_SCORE_VALUE = 10.0
// Changing the score will trigger the didSet
// that updates the labels and calls the updateScore
// function
gameScore = gameScore + HEADSHOT_SCORE_VALUE
}
// Your game logic when a game ends
func onGameOver() {
// When the game ends, call this function with the user's final
// score to resummon Triumph.
// @Params: score: Double
Triumph.gameOver(score: gameScore)
}
}
Score Labels
Triumph requires your to have two in-game score labels: a large, primary label, and a small, secondary label. These labels will display different things based on the game mode the user is playing.
For example, in a 1v1 tournament, the primary label will display the user's score, and the secondary label will display the user's tournament name. In a blitz tournament, the primary label will display the user's winnings in dollars, and the secondary label will display the user's score.
We will give you two methods that you use to get the string values for the primary and secondary label. Every time the score of your game changes, you should also update these labels.
using TriumphSDK;
public class GameScene : MonoBehaviour {
public TMP_Text LargeLabel;
public TMP_Text SmallLabel;
public int Score = 0;
public void IncreaseScore(int Increment)
{
score += increment;
Triumph.UpdateScore(score);
LargeLabel.text = Triumph.GetPrimaryLabel();
Smalllabel.text = Triumph.GetSecondaryLabel();
}
}
import TriumphSDK
class YourGameViewController {
let largeLabel: UILabel = UILabel()
let smalLabel: UILabel = UILabel()
var gameScore: Double? {
didSet {
// Whenever a score changes, we call updateScore with the new total score.
// Doing this on a didSet ensures we call this on every score update,
// although your implementation may differ
// @Params: score: Double
Triumph.updateScore(gameScore)
// Now that Triumph has an updated score for your game, we get the
// primary and secondary labels to display
largeLabel.text = Triumph.primaryLabel
smallLabel.text = Triumph.secondaryLabel
}
}
// User got a headshot!
func headShot() {
let HEADSHOT_SCORE_VALUE = 10.0
// Changing the score will trigger the didSet
// that updates the labels and calls the updateScore
// function
gameScore = gameScore + HEADSHOT_SCORE_VALUE
}
// Your game logic when the user loses and the game ends
func onGameOver() {
// When the game ends, call this function with the user's final
// score to resummon Triumph.
// @Params: with: Double
Triumph.gameOver(with: gameScore)
}
}