diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b2d24..48c5f16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [1.0.12] + +### 新增 + +* `ADManager` 新增 `EnterAdScenario(AD_Type, string)`,支持应用层显式上报广告场景到达。 +* `ADPlayer` 增加预热、重试和播放前钩子能力,用于平台层策略化调度。 + +### 修复 + +* `AsyncAdPlayer` 增强首播失败补偿和多次加载尝试,降低冷启动首次播放失败概率。 +* 初始化后可按广告位配置自动预热,避免高价值广告位首次点击才开始建链。 + # [1.0.0] 基础版本. diff --git a/Runtime/ADAggregator/ADManager.cs b/Runtime/ADAggregator/ADManager.cs index 425f70e..4f33740 100644 --- a/Runtime/ADAggregator/ADManager.cs +++ b/Runtime/ADAggregator/ADManager.cs @@ -80,6 +80,7 @@ namespace Runtime.ADAggregator controller.Init(adConfig , args); _adController = controller; _adConfig = adConfig; + PrewarmConfiguredPlayers(); onCallback?.Invoke(); #endif } @@ -102,12 +103,12 @@ namespace Runtime.ADAggregator return true; } #pragma warning disable CS0162 - if (AD_Dicts.ContainsKey(adType) == false) + if (!TryGetOrCreatePlayer(adType, out var player)) { - AD_Dicts[adType] = PlayerCreate(adType); + return false; } - return AD_Dicts[adType].IsReadly(); + return player.IsReadly(); #pragma warning restore CS0162 } @@ -122,9 +123,9 @@ namespace Runtime.ADAggregator } // Debug.LogError("准备加载广告" + adType); #pragma warning disable CS0162 - if (!IsRealy(adType)) + if (!IsRealy(adType) && TryGetOrCreatePlayer(adType, out var player)) { - AD_Dicts[adType].LoadAD(); + player.LoadAD(); } #pragma warning restore CS0162 } @@ -165,15 +166,15 @@ namespace Runtime.ADAggregator try { _curAsyncPlayer?.Kill(); - if (AD_Dicts.ContainsKey(adType) == false) + if (!TryGetOrCreatePlayer(adType, out var player)) { - AD_Dicts[adType] = PlayerCreate(adType); + callback?.Invoke(false); + return; } - var player = AD_Dicts[adType]; if (adType == AD_Type.AwardVideo) - GLOBAL_ShowAwardVideoBefore?.Invoke(player.Key , adScene); - _curAsyncPlayer = new AsyncAdPlayer(player, adScene, callback); + GLOBAL_ShowAwardVideoBefore?.Invoke(player.Key , NormalizeScenario(adScene)); + _curAsyncPlayer = new AsyncAdPlayer(player, NormalizeScenario(adScene), callback); } catch (Exception e) { @@ -194,11 +195,74 @@ namespace Runtime.ADAggregator } #pragma warning disable CS0162 var adPlayer = _adController.CreateAdPlayer(type); + if (adPlayer == null) + { + return null; + } adPlayer.ADType = type; return adPlayer; #pragma warning restore CS0162 } + public void EnterAdScenario(AD_Type adType, string adScene) + { +#if UNITY_EDITOR + return; +#endif + if (!_isInit || mIsGMModel) + { + return; + } +#pragma warning disable CS0162 + if (!TryGetOrCreatePlayer(adType, out var player)) + { + return; + } + + player.EnterAdScenario(NormalizeScenario(adScene)); +#pragma warning restore CS0162 + } + + private bool TryGetOrCreatePlayer(AD_Type type, out ADPlayer player) + { + if (AD_Dicts.TryGetValue(type, out player) && player != null) + { + return true; + } + + player = PlayerCreate(type); + if (player == null) + { + return false; + } + + AD_Dicts[type] = player; + return true; + } + + private void PrewarmConfiguredPlayers() + { + foreach (AD_Type adType in Enum.GetValues(typeof(AD_Type))) + { + if (!TryGetOrCreatePlayer(adType, out var player)) + { + continue; + } + + if (!player.AutoPreloadOnInit) + { + continue; + } + + player.LoadAD(); + } + } + + private static string NormalizeScenario(string scenario) + { + return string.IsNullOrWhiteSpace(scenario) ? "__default__" : scenario.Trim(); + } + public void CloseAd(AD_Type adType) { #if UNITY_EDITOR @@ -323,4 +387,4 @@ namespace Runtime.ADAggregator GLOBAL_ShowAwardVideoComplete?.Invoke(isComplete); } } -} \ No newline at end of file +} diff --git a/Runtime/ADAggregator/ADPlayer.cs b/Runtime/ADAggregator/ADPlayer.cs index a411bbb..266d013 100644 --- a/Runtime/ADAggregator/ADPlayer.cs +++ b/Runtime/ADAggregator/ADPlayer.cs @@ -15,9 +15,32 @@ namespace Runtime.ADAggregator public Action OnErrorAction; public AD_Type ADType { get; internal set; } - public int State => curState; + public virtual int MaxLoadAttempts + { + get + { + return ADType == AD_Type.AwardVideo ? 2 : 1; + } + } + + public virtual float LoadRetryDelaySeconds + { + get + { + return ADType == AD_Type.AwardVideo ? 0.75f : 0f; + } + } + + public virtual bool AutoPreloadOnInit + { + get + { + return false; + } + } + public ADPlayer Init(string key) { this.Key = key; @@ -45,6 +68,14 @@ namespace Runtime.ADAggregator { } + public virtual void OnPlayRequestStarted() + { + } + + public virtual void EnterAdScenario(string scenario) + { + } + /// /// 主动关闭广告 /// @@ -59,4 +90,4 @@ namespace Runtime.ADAggregator curState = 0; } } -} \ No newline at end of file +} diff --git a/Runtime/ADAggregator/AsyncAdPlayer.cs b/Runtime/ADAggregator/AsyncAdPlayer.cs index 6801ad8..a11204e 100644 --- a/Runtime/ADAggregator/AsyncAdPlayer.cs +++ b/Runtime/ADAggregator/AsyncAdPlayer.cs @@ -10,6 +10,8 @@ namespace Runtime.ADAggregator private bool firstLoad; private bool isKill; private bool isUpdate; + private int loadAttempts; + private float nextLoadRetryTime; private AdTimeHandler overHandler; private string _Ad_scene; @@ -23,6 +25,8 @@ namespace Runtime.ADAggregator this._callback = callback; this.isKill = false; this.firstLoad = true; + this.loadAttempts = 0; + this.nextLoadRetryTime = 0f; this._adPlayer = player; if (_adPlayer == null) { @@ -36,6 +40,7 @@ namespace Runtime.ADAggregator ADManager.Instance.OpenMask(); _adPlayer.OnErrorAction = OnError; _adPlayer.AdScene = this._Ad_scene; + _adPlayer.OnPlayRequestStarted(); isUpdate = true; ADManager.Instance.AddUpdater(DoUpdate); } @@ -83,14 +88,20 @@ namespace Runtime.ADAggregator } else if(!_adPlayer.IsLoading()) { - if (firstLoad) + if (loadAttempts < _adPlayer.MaxLoadAttempts) { + if (this._outTime < nextLoadRetryTime) + { + return; + } + #if UNITY_EDITOR Debug.LogError("开始加载广告: " + this._adPlayer.Key); #endif - this._outTime = 0; _adPlayer.LoadAD(); + loadAttempts++; firstLoad = false; + nextLoadRetryTime = this._outTime + _adPlayer.LoadRetryDelaySeconds; } else { diff --git a/package.json b/package.json index d0e2e51..d297f04 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "com.foldcc.cc-framework.commercialization", "displayName": "CC-Framework.commercialization", "description": "商业化sdk通用组件,包含广告、内购、用户统计、归因统计等", - "version": "1.0.11", + "version": "1.0.12", "unity": "2021.1", "license": "MIT", "repository": {