using System; using UnityEngine; namespace Runtime.ADAggregator { public class AsyncAdPlayer { private enum AsyncPlayPhase { Loading, ShowPending, Playing, Closing, Completed } private const float LoadTimeoutSeconds = 15f; private const float ShowAckTimeoutSeconds = 2f; private Action _callback; private ADPlayer _adPlayer; private bool isKill; private bool isUpdate; private int loadAttempts; private float nextLoadRetryTime; private AdTimeHandler overHandler; private AdTimeHandler _showPendingHandler; private string _adScene; private AsyncPlayPhase _phase; private float _loadElapsed; public AsyncAdPlayer(ADPlayer player , string adScene, Action callback) { _adScene = adScene; _loadElapsed = 0f; _callback = callback; isKill = false; loadAttempts = 0; nextLoadRetryTime = 0f; _adPlayer = player; _phase = AsyncPlayPhase.Loading; if (_adPlayer == null) { #if UNITY_EDITOR Debug.LogError("无法播放指定的广告"); #endif _callback?.Invoke(false); Kill(); return; } ADManager.Instance.OpenMask(); _adPlayer.OnErrorAction = OnError; _adPlayer.OnShowStartedAction = OnShowStarted; _adPlayer.AdScene = _adScene; _adPlayer.OnPlayRequestStarted(); isUpdate = true; ADManager.Instance.AddUpdater(DoUpdate); } private void OnError() { #if UNITY_EDITOR Debug.LogError("广告异常: " + this._adPlayer.Key); #endif if (_phase == AsyncPlayPhase.Loading) { return; } Fail(false); } private void DoUpdate() { if (!isUpdate) { return; } switch (_phase) { case AsyncPlayPhase.Loading: UpdateLoading(); break; } } private void UpdateLoading() { _loadElapsed += Time.deltaTime; if (_loadElapsed >= LoadTimeoutSeconds) { Fail(false); return; } if (_adPlayer.IsReadly()) { BeginShow(); } else if (!_adPlayer.IsLoading()) { if (loadAttempts < _adPlayer.MaxLoadAttempts) { if (_loadElapsed < nextLoadRetryTime) { return; } #if UNITY_EDITOR Debug.LogError("开始加载广告: " + this._adPlayer.Key); #endif _adPlayer.LoadAD(); loadAttempts++; nextLoadRetryTime = _loadElapsed + _adPlayer.LoadRetryDelaySeconds; } else { Fail(false); } } } private void BeginShow() { #if UNITY_EDITOR Debug.LogError("开始播放广告: " + _adPlayer.Key); #endif try { _phase = AsyncPlayPhase.ShowPending; _showPendingHandler = ADManager.Instance.CreateTimer( _adPlayer.ShowPendingTimeoutSeconds > 0 ? _adPlayer.ShowPendingTimeoutSeconds : ShowAckTimeoutSeconds, () => Fail(false)); _adPlayer.ShowAD(OnCloseAD, OnComplete); isUpdate = false; ADManager.Instance.RemoveUpdater(DoUpdate); } catch (Exception exception) { Debug.LogError(exception); _showPendingHandler?.Kill(); Fail(false); } } private void OnShowStarted() { if (isKill) { return; } _phase = AsyncPlayPhase.Playing; _showPendingHandler?.Kill(); ADManager.Instance.CloseMask(); } private void OnCloseAD() { #if UNITY_EDITOR Debug.LogError("关闭广告: " + _adPlayer.Key); #endif _phase = AsyncPlayPhase.Closing; _showPendingHandler?.Kill(); if (overHandler == null) { overHandler = ADManager.Instance.CreateTimer(1.5f, () => { _callback?.Invoke(false); Clear(); }); } } private void OnComplete(bool obj) { _phase = AsyncPlayPhase.Completed; _showPendingHandler?.Kill(); overHandler?.Kill(); overHandler = ADManager.Instance.CreateTimer(0.05f, () => { if (_adPlayer != null && _adPlayer.ADType == AD_Type.AwardVideo) { ADManager.Instance.OnVideoComplete(obj); } _callback?.Invoke(obj); Clear(); }); } private void Fail(bool result) { _callback?.Invoke(result); Kill(); } //销毁广告 public void Kill() { if (isKill) return; ADManager.Instance.RemoveUpdater(DoUpdate); Clear(); } private void Clear() { ADManager.Instance.CloseMask(); isKill = true; isUpdate = false; if (_adPlayer != null) { _adPlayer.OnErrorAction = null; _adPlayer.OnShowStartedAction = null; } _callback = null; _adPlayer = null; overHandler = null; _showPendingHandler = null; } } }