// Lumarcade SDK for Unity WebGL (MIT). Attach to a GameObject named "Lumarcade" in your first scene. // In the Editor and non-WebGL builds every call is a safe no-op so you can test normally. using System; using System.Runtime.InteropServices; using UnityEngine; public class Lumarcade : MonoBehaviour { public string gameId = "your-game-id"; public static Lumarcade Instance { get; private set; } public static bool IsReady { get; private set; } public event Action Ready; // JSON: user, platform, inventory, equipped public event Action RewardedResult; // true → give the reward public event Action AdFinished; // interstitial closed (or skipped for Pass players) public event Action LevelReward; // JSON: { granted: [{id, name}] } public event Action SaveLoaded; // JSON: { key, value } #if UNITY_WEBGL && !UNITY_EDITOR [DllImport("__Internal")] static extern void PF_Init(string gameId, string objectName); [DllImport("__Internal")] static extern void PF_GameplayStart(); [DllImport("__Internal")] static extern void PF_GameplayStop(); [DllImport("__Internal")] static extern void PF_LoadingProgress(float p); [DllImport("__Internal")] static extern void PF_Loaded(); [DllImport("__Internal")] static extern void PF_LevelComplete(int level, int score); [DllImport("__Internal")] static extern void PF_ShowInterstitial(); [DllImport("__Internal")] static extern void PF_ShowRewarded(); [DllImport("__Internal")] static extern void PF_SaveSet(string key, string json); [DllImport("__Internal")] static extern void PF_SaveGet(string key); [DllImport("__Internal")] static extern int PF_IsSubscriber(); [DllImport("__Internal")] static extern string PF_Equipped(string type); [DllImport("__Internal")] static extern void PF_SubmitScore(int score); #else static void PF_Init(string g, string o) { Instance?.OnLumarcadeReady("{\"standalone\":true}"); } static void PF_GameplayStart() { } static void PF_GameplayStop() { } static void PF_LoadingProgress(float p) { } static void PF_Loaded() { } static void PF_LevelComplete(int level, int score) { } static void PF_ShowInterstitial() { Instance?.OnAdFinished("interstitial"); } static void PF_ShowRewarded() { Instance?.OnRewardedResult("1"); } static void PF_SaveSet(string key, string json) { PlayerPrefs.SetString("pf_" + key, json); } static void PF_SaveGet(string key) { Instance?.OnSaveLoaded("{\"key\":\"" + key + "\",\"value\":" + PlayerPrefs.GetString("pf_" + key, "null") + "}"); } static int PF_IsSubscriber() { return 0; } static string PF_Equipped(string type) { return ""; } static void PF_SubmitScore(int score) { } #endif void Awake() { if (Instance != null) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); PF_Init(gameId, gameObject.name); } public void GameplayStart() => PF_GameplayStart(); public void GameplayStop() => PF_GameplayStop(); public void LoadingProgress(float p) => PF_LoadingProgress(p); public void Loaded() => PF_Loaded(); public void LevelComplete(int level, int score) => PF_LevelComplete(level, score); public void ShowInterstitial() => PF_ShowInterstitial(); public void ShowRewarded() => PF_ShowRewarded(); public void Save(string key, string json) => PF_SaveSet(key, json); public void Load(string key) => PF_SaveGet(key); public bool IsSubscriber => PF_IsSubscriber() == 1; /// Equipped item id for a slot type such as "car_skin" or "launcher" (empty if none). public string Equipped(string type) => PF_Equipped(type) ?? ""; public void SubmitScore(int score) => PF_SubmitScore(score); // ---- callbacks from the .jslib (names must match) ---- void OnLumarcadeReady(string json) { IsReady = true; Ready?.Invoke(json); } void OnLumarcadeError(string message) { Debug.LogWarning("Lumarcade: " + message); IsReady = true; Ready?.Invoke("{}"); } void OnRewardedResult(string ok) => RewardedResult?.Invoke(ok == "1"); void OnAdFinished(string kind) => AdFinished?.Invoke(); void OnLevelReward(string json) => LevelReward?.Invoke(json); void OnSaveLoaded(string json) => SaveLoaded?.Invoke(json); }