Unity SDK
C# bindings for Unity WebGL games. Submit scores, show ads, trigger haptics, and spend platform coins — all through the static YesSDK class.
Getting Started
Install via UPM
Yes from any script.Requirements
- Unity 2021.3 LTS or newer
- WebGL build target (the SDK is no-op on other platforms outside the Editor)
- .NET Standard 2.1 or .NET Framework 4.x
Install (Package Manager)
- Open Window → Package Manager
- Click the + button and choose Add package from git URL…
- Paste the URL below and click Add
https://github.com/playonyes/yes-sdk-unity.git
Install (manifest.json)
Alternatively, add the dependency directly to Packages/manifest.json:
{"dependencies": {"com.yes.sdk": "https://github.com/playonyes/yes-sdk-unity.git"}}
Pinning a version
Append #v1.0.0 (or any tag/commit) to the URL to pin a specific release:
https://github.com/playonyes/yes-sdk-unity.git#v1.0.0
Quick Start
A minimal MonoBehaviour that fetches the player and submits a score:
using UnityEngine;using Yes;public class GameController : MonoBehaviour{private void Start(){YesSDK.OnReady(async () =>{Player player = await YesSDK.GetPlayerAsync();Debug.Log($"Playing as {player.username}");});}public async void OnGameOver(int finalScore){SubmitScoreResult result = await YesSDK.SubmitScoreAsync(finalScore);if (result.isNewBest){YesSDK.Haptic(HapticStyle.Success);}}}
Configuration
Call YesSDK.Configure() once before the first SDK method if you want to override defaults. The Editor and standalone builds run a mock provider that returns realistic stub responses — you can develop your game without ever touching the platform.
using UnityEngine;using Yes;public static class YesBootstrap{[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]private static void Configure(){YesSDK.Configure(new YesSDKConfig{Debug = true, // log every bridge messageTimeoutMs = 10000, // per-request timeout (default 10s)UseMockProviderOutsideWebGL = true, // mock responses in Editor (default)});}}
API Reference
Lifecycle
YesSDK.OnReady()#public static void OnReady(Action callback)
Register a callback that fires once the SDK has finished bootstrapping. Invoked immediately if the SDK is already ready.
Parameters
| Name | Type | Description |
|---|---|---|
callback | Action | Invoked when the SDK is ready. Null callbacks are ignored. |
Example
YesSDK.OnReady(() =>{Debug.Log("SDK ready — safe to call any YesSDK method.");});
YesSDK.Configure()#public static void Configure(YesSDKConfig config)
Apply a custom configuration. Call before the first SDK method for the timeout to take effect; the Debug flag is honoured at any time.
Parameters
| Name | Type | Description |
|---|---|---|
config | YesSDKConfig | Configuration object. Pass null to reset to defaults. |
Example
YesSDK.Configure(new YesSDKConfig { Debug = true, TimeoutMs = 15000 });
Scores
Boost player retention
YesSDK.SubmitScoreAsync()#public static Task<SubmitScoreResult> SubmitScoreAsync(int score, SubmitScoreOptions options = null)
Submit a score to the leaderboard. Throws ArgumentOutOfRangeException if score is negative.
Parameters
| Name | Type | Description |
|---|---|---|
score | int | The score to submit. Must be non-negative. |
options? | SubmitScoreOptions | Optional metadata (MetadataJson string). |
Returns
Task<SubmitScoreResult>{ isNewBest, rank, score } — isNewBest is true when this beats the player's previous high score.
Example
SubmitScoreResult result = await YesSDK.SubmitScoreAsync(score);if (result.isNewBest){ShowMessage($"New best! Rank #{result.rank}");YesSDK.Haptic(HapticStyle.Success);}
Player
YesSDK.GetPlayerAsync()#public static Task<Player> GetPlayerAsync()
Fetch the current player's profile. Cache the result — it doesn't change during a session.
Returns
Task<Player>{ id, username, avatarUrl } — use to personalise your game UI.
Example
Player player = await YesSDK.GetPlayerAsync();playerNameLabel.text = player.username;if (!string.IsNullOrEmpty(player.avatarUrl)){StartCoroutine(LoadAvatar(player.avatarUrl));}
Ads
Two ad formats
YesSDK.ShowRewardedAdAsync()#public static Task<RewardedAdResult> ShowRewardedAdAsync()
Display a rewarded video ad. The player can earn rewards by watching the full ad.
Returns
Task<RewardedAdResult>{ rewarded, errorCode, errorMessage } — only grant rewards when rewarded is true.
Example
RewardedAdResult ad = await YesSDK.ShowRewardedAdAsync();if (ad.rewarded){player.coins += 100;ShowMessage("You earned 100 coins!");}else if (ad.errorCode == "USER_DISMISSED"){ShowMessage("Watch the full ad to earn rewards");}else if (ad.errorCode == "NOT_LOADED"){ShowMessage("No ad available right now");}
YesSDK.IsRewardedAdReadyAsync()#public static Task<AdReadyStatus> IsRewardedAdReadyAsync()
Check if a rewarded ad is loaded and available. Use to conditionally enable a 'Watch Ad' button.
Returns
Task<AdReadyStatus>{ ready } — true when an ad is ready to show.
Example
AdReadyStatus status = await YesSDK.IsRewardedAdReadyAsync();watchAdButton.interactable = status.ready;
YesSDK.ShowInterstitialAdAsync()#public static Task<InterstitialAdResult> ShowInterstitialAdAsync()
Show an interstitial ad between natural game moments. Rate-limited — if called too frequently, it resolves immediately without showing.
Returns
Task<InterstitialAdResult>{ shown, errorCode, errorMessage } — shown is true if the ad was actually displayed.
Example
public async void OnLevelComplete(){await YesSDK.ShowInterstitialAdAsync();LoadNextLevel();}
YesSDK.IsInterstitialAdReadyAsync()#public static Task<AdReadyStatus> IsInterstitialAdReadyAsync()
Check if an interstitial is available and not rate-limited. Returns false during the cooldown period after a previous interstitial.
Returns
Task<AdReadyStatus>{ ready } — true when an interstitial can be shown right now.
Example
AdReadyStatus status = await YesSDK.IsInterstitialAdReadyAsync();if (status.ready){await YesSDK.ShowInterstitialAdAsync();}
Haptics
YesSDK.Haptic()#public static void Haptic(HapticStyle style = HapticStyle.Medium)
Trigger haptic feedback on the player's device. Fire-and-forget — falls back silently on devices without haptic support.
Parameters
| Name | Type | Description |
|---|---|---|
style? | HapticStyle | The haptic style. Defaults to HapticStyle.Medium. |
Example
YesSDK.Haptic(); // default Medium tapYesSDK.Haptic(HapticStyle.Success); // positive feedbackYesSDK.Haptic(HapticStyle.Error); // negative feedback
| Enum | When to use |
|---|---|
HapticStyle.Light | Subtle UI taps |
HapticStyle.Medium | Default — general feedback |
HapticStyle.Heavy | Impacts, collisions |
HapticStyle.Success | Score submitted, level cleared |
HapticStyle.Warning | Low health, almost out of time |
HapticStyle.Error | Failed action, game over |
HapticStyle.Selection | Menu navigation, picker changes |
Coins
Platform-controlled pricing
YesSDK.PurchaseAsync()#public static Task<PurchaseResult> PurchaseAsync(PurchaseTier tier, PurchaseOptions options = null)
Prompt the player to spend coins from their wallet. The platform shows a native confirmation modal. Always check result.success before granting in-game content.
Parameters
| Name | Type | Description |
|---|---|---|
tier | PurchaseTier | The coin tier to charge (Tier1–Tier4). |
options.Label? | string | Label shown in the confirmation modal (e.g. 'Unlock Level Pack'). |
Returns
Task<PurchaseResult>{ success, tierId, coinsSpent, reason } — reason is "cancelled", "insufficient_funds", or "error" on failure.
Example
PurchaseResult result = await YesSDK.PurchaseAsync(PurchaseTier.Tier2,new PurchaseOptions("Extra Lives"));if (result.success){GrantExtraLives();YesSDK.Haptic(HapticStyle.Success);}else if (result.reason == "insufficient_funds"){ShowMessage("Not enough coins!");}else if (result.reason == "cancelled"){// Player tapped cancel — do nothing}
| Enum | Coins |
|---|---|
PurchaseTier.Tier1 | 50 |
PurchaseTier.Tier2 | 150 |
PurchaseTier.Tier3 | 500 |
PurchaseTier.Tier4 | 1000 |
Language
Match the app's language
GetLanguage() to read it and localize your game's UI so everything feels native to them.YesSDK.GetLanguage()#public static string GetLanguage()
Returns the app's current language code. Synchronous — no await needed. Call at game init to set your UI language.
Returns
stringLanguage code: "en" (English) or "tr" (Turkish). Defaults to "en".
Example
string lang = YesSDK.GetLanguage();if (lang == "tr"){SetUILanguage(Language.Turkish);}else{SetUILanguage(Language.English);}
Full Example
A complete MonoBehaviour that wires up every SDK feature:
using UnityEngine;using UnityEngine.UI;using Yes;public class GameController : MonoBehaviour{[SerializeField] private Text playerNameLabel;[SerializeField] private Button watchAdButton;[SerializeField] private Button buyExtraLivesButton;private Player _player;private int _score;private void Start(){YesSDK.OnReady(async () =>{// Personalise the UI_player = await YesSDK.GetPlayerAsync();playerNameLabel.text = _player.username;// Localise to match the app's languageApplyLanguage(YesSDK.GetLanguage());// Only show "Watch Ad" if an ad is readyvar status = await YesSDK.IsRewardedAdReadyAsync();watchAdButton.interactable = status.ready;});}public async void OnLevelComplete(int levelScore){_score += levelScore;// Submit score (fire and forget the await)var result = await YesSDK.SubmitScoreAsync(_score);if (result.isNewBest){YesSDK.Haptic(HapticStyle.Success);}// Interstitial between levelsawait YesSDK.ShowInterstitialAdAsync();LoadNextLevel();}public async void OnWatchAdForLife(){var ad = await YesSDK.ShowRewardedAdAsync();if (ad.rewarded){GrantExtraLife();YesSDK.Haptic(HapticStyle.Success);}}public async void OnBuyExtraLives(){var result = await YesSDK.PurchaseAsync(PurchaseTier.Tier2,new PurchaseOptions("Extra Lives"));if (result.success){GrantExtraLives(count: 3);YesSDK.Haptic(HapticStyle.Success);}else if (result.reason == "insufficient_funds"){ShowMessage("Not enough coins!");}}private void ApplyLanguage(string code) { /* ... */ }private void LoadNextLevel() { /* ... */ }private void GrantExtraLife() { /* ... */ }private void GrantExtraLives(int count) { /* ... */ }private void ShowMessage(string text) { /* ... */ }}
Best Practices
Wait for OnReady
Calls before the SDK has bootstrapped will queue and resolve once ready, but for calls that block UI (player profile, ad readiness) wrap them in OnReady or check YesSDK.IsReady first.
YesSDK.OnReady(async () =>{Player player = await YesSDK.GetPlayerAsync();nameLabel.text = player.username;});
Always check ad results
Never grant a reward without first checking result.rewarded. Players can dismiss or skip ads, and granting rewards anyway breaks the economy.
Test in the Editor with mock mode
By default, the SDK returns realistic mock responses in the Unity Editor and any non-WebGL build. You can iterate on score submission, ad flows, and purchases without ever building to WebGL. Disable via UseMockProviderOutsideWebGL = false if you need to debug the bridge layer.
Score submission timing
Submit scores at natural game moments — end of level, game over, or achievement completion. Avoid spamming submissions during gameplay.
Reference sample
A complete IMGUI demo exercising every API is included with the package at Samples~/BasicIntegration/YesSDKDemo.cs. Import it via the Package Manager → Samples tab.