// BulletHellTemplate/Monetization/MonetizationManager.cs using Cysharp.Threading.Tasks; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace BulletHellTemplate { /// /// Holds currency cache & thin wrappers that forward purchase calls /// to . /// [DisallowMultipleComponent] public sealed class MonetizationManager : MonoBehaviour { public static MonetizationManager Singleton { get; private set; } /// Raised every time a local currency value is updated. public static event Action OnCurrencyChanged; /*──────────────────── Unity ────────────────────*/ private void Awake() { if (Singleton == null) { Singleton = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } /*───────────────── Purchases (wrappers) ─────────────────*/ public UniTask PurchaseShopItemAsync(ShopItem item) => BackendManager.Service.PurchaseShopItemAsync(item); public UniTask ClaimBattlePassRewardAsync(BattlePassItem reward) => BackendManager.Service.ClaimBattlePassRewardAsync(reward); /*──────────────────── Currency API ────────────────────*/ /// Returns current amount stored in PlayerPrefs. public static int GetCurrency(string currencyKey) => PlayerSave.GetCurrency(currencyKey); /// /// Sets the amount locally, fires , /// and (optionally) pushes the change to the active backend. /// public static void SetCurrency(string currencyKey, int amount, bool pushToBackend = true) { PlayerSave.SetCurrency(currencyKey, amount); OnCurrencyChanged?.Invoke(currencyKey, amount); } /// Returns the sprite associated with a currency (or null). public Sprite GetCurrencyIcon(string currencyKey) { var entry = GameInstance.Singleton.currencyData.Find(c => c.coinID == currencyKey); return entry != null ? entry.icon : null; } } }