using System; using System.Collections.Generic; using UnityEngine; namespace Runtime.ADAggregator { public class ADManager : MonoBehaviour { private static ADManager _instance; private static bool mIsCreate = false; private static bool mIsGMModel = false; public static ADManager Instance { get { if (_instance == null && !mIsCreate) { var objs = FindObjectsOfType(); for (int i = 0; i < objs.Length; i++) { Destroy(objs[i]); } _instance = new GameObject().AddComponent(); _instance.name = "[GameUpdater] NoInit"; DontDestroyOnLoad(_instance); _instance.InitTimeSystem(); mIsCreate = true; } return _instance; } private set => _instance = value; } #if UNITY_ANDROID public AndroidJavaObject activityContext { get; private set; } #endif /// /// 用于记录广告位状态 0 未加载 、 1 加载中、 2 加载成功 /// private Dictionary AD_Dicts; private ADConfig _adConfig; private IAdController _adController; private AsyncAdPlayer _curAsyncPlayer; private string _userId; /// /// 全局任意视频广告播放结束后事件, bool 表示是否完成奖励 /// public event Action GLOBAL_ShowAwardVideoComplete; /// /// 全局任意视频广告玩家点击播放时 /// public event Action GLOBAL_ShowAwardVideoBefore; public string UserId => _userId; #pragma warning disable CS0414 private bool _isInit = false; #pragma warning restore CS0414 public void Init(Action onCallback, string userId, ADConfig adConfig, IAdController controller, params object[] args) { _isInit = true; _instance.name = "[GameUpdater] Init"; AD_Dicts = new Dictionary(); _userId = userId; #if UNITY_EDITOR onCallback?.Invoke(); #else controller.Init(adConfig , args); _adController = controller; _adConfig = adConfig; PrewarmConfiguredPlayers(); onCallback?.Invoke(); #endif } /// /// 测试模式,此模式下,不会播放、加载任何广告,但是会模拟广告播放成功,正式版本不能调用此方法 /// public void SetTestModel() { mIsGMModel = true; } public bool IsRealy(AD_Type adType) { #if UNITY_EDITOR return true; #endif if (!_isInit || mIsGMModel) { return true; } #pragma warning disable CS0162 if (!TryGetOrCreatePlayer(adType, out var player)) { return false; } return player.IsReadly(); #pragma warning restore CS0162 } public void LoadAD(AD_Type adType) { #if UNITY_EDITOR return; #endif if (!_isInit || mIsGMModel) { return; } // Debug.LogError("准备加载广告" + adType); #pragma warning disable CS0162 if (!IsRealy(adType) && TryGetOrCreatePlayer(adType, out var player)) { player.LoadAD(); } #pragma warning restore CS0162 } /// /// 检查网络状态 /// /// public bool CheckNetwork() { return Application.internetReachability != NetworkReachability.NotReachable; } /// /// 直接加载并播放广告 /// /// /// public void AsyncPlayAD(AD_Type adType, string adScene, Action callback) { #if UNITY_EDITOR if (adType == AD_Type.AwardVideo) { this.OnVideoComplete(true); } callback?.Invoke(true); return; #endif if (!_isInit || mIsGMModel) { callback?.Invoke(true); return; } _adController.EventLog("adScene", adScene); try { _curAsyncPlayer?.Kill(); if (!TryGetOrCreatePlayer(adType, out var player)) { callback?.Invoke(false); return; } if (adType == AD_Type.AwardVideo) GLOBAL_ShowAwardVideoBefore?.Invoke(player.Key , NormalizeScenario(adScene)); _curAsyncPlayer = new AsyncAdPlayer(player, NormalizeScenario(adScene), callback); } catch (Exception e) { Debug.LogError(e); _adController.EventLog("error", "showAdError", e.Message); callback?.Invoke(false); } } public ADPlayer PlayerCreate(AD_Type type) { #if UNITY_EDITOR return null; #endif if (!_isInit || mIsGMModel) { return null; } #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 return; #endif if (!_isInit || mIsGMModel) { return; } #pragma warning disable CS0162 if (adType != AD_Type.AwardVideo) { if (AD_Dicts.ContainsKey(adType)) { AD_Dicts[adType]?.CloseAD(); } } #pragma warning restore CS0162 } #region TimeSystem private List _updateList; private const int DefaultLength = 1024; private List _timeHandlers; private void InitTimeSystem() { this._updateList = new List(DefaultLength); this._timeHandlers = new List(); } private void _InvokeUpdate(List list) { for (int i = list.Count - 1; i >= 0; i--) { //在遍历时可能会出现外部操作list导致Count改变 if (i >= list.Count) continue; if (list[i] == null) { list.RemoveAt(i); } else { list[i].Invoke(); } } for (int i = this._timeHandlers.Count - 1; i >= 0; i--) { var timeHandler = this._timeHandlers[i]; if (timeHandler == null || timeHandler.IsDone || timeHandler._isKill) { this._timeHandlers.RemoveAt(i); } else { timeHandler.Update(); } } } private void Update() => this._InvokeUpdate(this._updateList); public AdTimeHandler CreateTimer(float delay, Action callback, Action update = null) { if (delay <= 0) { callback.Invoke(); return null; } var timer = new AdTimeHandler(delay, callback, update); this._timeHandlers.Add(timer); return timer; } public AdTimeHandler CreateOneFrameTimer(Action callback, Action update = null) { return this.CreateTimer(0.001f, callback, update); } public AdTimeHandler CreateTimer(GameObject gameObj, float delay, Action callback, Action update = null) { if (delay <= 0) { callback.Invoke(); return null; } var timer = new AdTimeHandler(gameObj, delay, callback, update); this._timeHandlers.Add(timer); return timer; } public void AddUpdater(Action updater) { this._updateList.Add(updater); } public void RemoveUpdater(Action updater) { this._updateList.Remove(updater); } #endregion public void CloseMask() { _adController.SetMask(false); } public void OpenMask() { _adController.SetMask(true); } internal void OnVideoComplete(bool isComplete) { GLOBAL_ShowAwardVideoComplete?.Invoke(isComplete); } } }