namespace Guru { using UnityEngine; using System; public partial class GuruSDK { private static AdsInitSpec _adInitSpec; /// /// 启动广告服务 /// public static void StartAds(AdsInitSpec spec = null) { _adInitSpec = spec; if (InitConfig.UseCustomConsent) { Debug.Log($"{Tag} --- Call StartAdsWithCustomConsent when you use custom consent, and pass the result (boolean) to the method."); return; } // 默认的启动顺序是先启动Consent后, 根据用户回调的结果来启动广告 Instance.StartConsentFlow(); } /// /// 是否已经购买了去广告 /// /// public static void StartAds(bool buyNoAds = false) { StartAds(AdsInitSpec.BuildWithNoAds()); // 按照默认的去广告来生成广告启动配置 } /// /// 使用自定义的Consent, 获取用户授权后, 调用此方法 /// /// /// Consent 引导的类型, 如果使用了 MAX 的 consent 请填写 max /// 广告启动配置 public static void StartAdsWithCustomConsent(bool userAllow = true, string consentName = "custom", AdsInitSpec spec = null) { #if UNITY_IOS _attType = consentName; InitAttStatus(); #endif if (userAllow) { #if UNITY_IOS CheckAttStatus(); #else StartAdService(spec); #endif } else { Debug.Log($"{Tag} --- User refuse to provide ads Id, Ads Service will be cancelled"); } } /// /// 使用自定义的Consent, 获取用户授权后, 调用此方法 /// /// 自定义 Consent 的用户授权结果 /// Consent引导名称 /// 是否已经购买了去广告 public static void StartAdsWithCustomConsent(bool userAllow = true, string consentName = "custom", bool buyNoAds = false) { StartAdsWithCustomConsent(userAllow, consentName, AdsInitSpec.BuildWithNoAds()); } #region Guru Consent private bool _hasConsentCalled = false; /// /// 启动Consent流程 /// 因为之后规划广告流程会放在 Consent 初始化之后, 因此请求广告的时候会需要先请求 Consent /// private void StartConsentFlow() { if (_hasConsentCalled) return; _hasConsentCalled = true; bool enableCountryCheck = false; string dmaMapRule = ""; if (_appServicesConfig != null && _appServicesConfig.parameters != null) { enableCountryCheck = _appServicesConfig.DMACountryCheck(); dmaMapRule = _appServicesConfig.DMAMapRule(); } #if UNITY_IOS InitAttStatus(); // Consent 启动前记录 ATT 初始值 #endif Debug.Log($"{Tag} --- Call:StartConsentFlow ---"); GuruConsent.StartConsent(OnGuruConsentOver, dmaMapRule:dmaMapRule, enableCountryCheck:enableCountryCheck); } /// /// Guru Consent flow is Over /// /// private void OnGuruConsentOver(int code) { // 无论状态如何, 都在回调内启动广告初始化 StartAdService(_adInitSpec); // 调用回调 Callbacks.ConsentFlow._onConsentResult?.Invoke(code); #if UNITY_IOS CheckAttStatus(); // [iOS] Consent 启动后检查 ATT 初始值 #endif // 内部处理后继逻辑 switch(code) { case GuruConsent.StatusCode.OBTAINED: case GuruConsent.StatusCode.NOT_AVAILABLE: // 已获取授权, 或者地区不可用, ATT 尚未启动 // TODO: 添加后继处理逻辑 break; } } #endregion #region IOS ATT 广告授权流程 #if UNITY_IOS private static string _initialAttStatus; private static String _attType = "admob"; private static bool _autoReCallAtt = false; /// /// 显示系统的 ATT 弹窗 /// public static void RequestAttDialog() { LogI($"RequestATTDialog"); ATTManager.RequestATTDailog(ReportAttStatus); } /// /// 初始化 ATT 状态 /// public static void InitAttStatus() { _attType = InitConfig.UseCustomConsent ? ATTManager.GUIDE_TYPE_CUSTOM : ATTManager.GUIDE_TYPE_ADMOB; // 点位属性确定 _initialAttStatus = ATTManager.GetStatus(); SetUserProperty(Analytics.ParameterATTStatus, _initialAttStatus); // 上报一个初始的状态 } /// /// iOS 平台检查 ATT 状态 /// private static void CheckAttStatus(bool autoReCall = false) { _autoReCallAtt = autoReCall; // Delay 1s to get the user choice Delay(1, () => ATTManager.CheckStatus(ReportAttStatus)); } private static void ReportAttStatus(string status) { LogI($"{Tag} --- Get Att status:{status} att Type:{_attType} recall:{_autoReCallAtt}"); SetUserProperty(Analytics.ParameterATTStatus, status); // 当前的状态 if (!string.IsNullOrEmpty(status) && status != _initialAttStatus && status != ATTManager.ATT_STATUS_NOT_DETERMINED) { // 上报点位: Analytics.AttResult(status, _attType); } switch(status) { case ATTManager.ATT_STATUS_NOT_DETERMINED: // ATT 状态未知, 请求弹窗 if(_autoReCallAtt) RequestAttDialog(); break; case ATTManager.ATT_STATUS_RESTRICTED: case ATTManager.ATT_STATUS_DENIED: // ATT 状态受限, 或者被拒绝 break; case ATTManager.ATT_STATUS_AUTHORIZED: // ATT 状态已授权 break; } } #endif #endregion #region Ad Services private static bool _initAdsCompleted = false; /// /// 启动广告服务 /// internal static void StartAdService(AdsInitSpec spec = null) { LogI($"StartAdService"); if (spec == null) { spec = AdsInitSpec.BuildDefault(InitConfig.AutoLoadWhenAdsReady, IsDebugMode); if (ADService.Instance.IsBuyNoAds) { spec = AdsInitSpec.BuildWithNoAds(InitConfig.AutoLoadWhenAdsReady, IsDebugMode); } } ADService.Instance.StartService(OnAdsInitComplete, spec); //--------- Callbacks ----------- ADService.OnBannerLoaded = OnBannerLoaded; ADService.OnInterstitialLoaded = OnInterstitialLoaded; ADService.OnInterstitialFailed = OnInterstitialFailed; ADService.OnRewardLoaded = OnRewardLoaded; ADService.OnRewardFailed = OnRewardFailed; } private static void OnBannerLoaded() => Callbacks.Ads._onBannerADLoaded?.Invoke(); private static void OnInterstitialLoaded() => Callbacks.Ads._onInterstitialADLoaded?.Invoke(); private static void OnInterstitialFailed() => Callbacks.Ads._onInterstitialADFailed?.Invoke(); private static void OnRewardLoaded() => Callbacks.Ads._onRewardedADLoaded?.Invoke(); private static void OnRewardFailed() => Callbacks.Ads._onRewardADFailed?.Invoke(); private static void OnAdsInitComplete() { _initAdsCompleted = true; Callbacks.Ads._onAdsInitComplete?.Invoke(); } private static bool CheckAdsReady() { if (!_initAdsCompleted) { LogE("Ads is not ready. Call first."); return false; } return true; } /// /// 显示Banner广告 /// /// public static void ShowBanner(string placement = "") { if (!CheckAdsReady()) return; ADService.Instance.ShowBanner(placement); } /// /// 隐藏Banner广告 /// public static void HideBanner() { if (!CheckAdsReady()) return; ADService.Instance.HideBanner(); } public static void LoadInterstitialAd() { if (!CheckAdsReady()) return; ADService.Instance.RequestInterstitialAD(); } public static bool IsInterstitialAdReady => ADService.Instance.IsInterstitialADReady(); /// /// 显示插屏广告 /// /// /// public static void ShowInterstitialAd(string placement = "", Action onDismissed = null) { if (!CheckAdsReady()) return; if (!ADService.Instance.IsInterstitialADReady()) { LogE("Interstitial is not ready. Call again."); LoadInterstitialAd(); return; } ADService.Instance.ShowInterstitialAD(placement, onDismissed); } public static void LoadRewardAd() { if (!CheckAdsReady()) return; ADService.Instance.RequestRewardedAD(); } public static bool IsRewardAdReady => ADService.Instance.IsRewardedADReady(); /// /// 显示激励视频广告 /// /// /// /// public static void ShowRewardAd(string placement = "", Action onRewarded = null, Action onFailed = null) { if (!CheckAdsReady()) return; if (!ADService.Instance.IsRewardedADReady()) { LogE("RewardAd is not ready. Call again."); LoadRewardAd(); return; } ADService.Instance.ShowRewardedAD(placement, onRewarded, onFailed); } #endregion #region MaxServices /// /// 显示Max调试菜单 /// public static void ShowMaxDebugPanel() { #if UNITY_EDITOR LogI($"Can not show Max Debug Panel in Editor, skipped."); return; #endif if (!ADService.Instance.IsInitialized) { LogI($"ADService is not initialized, call first."); return; } ADService.Instance.ShowMaxDebugPanel(); } #endregion } }