using System; using System.Collections; using System.Collections.Generic; using System.Linq; using GoogleMobileAds.Api; using UnityEngine; namespace WZ { public class AdmobNativeAdManager { private Dictionary _nativeAds = new Dictionary(); private Dictionary _adRevenueCache = new Dictionary(); private Dictionary _retryCounters = new Dictionary(); public void InitializeAdUnits(List adUnitIds) { foreach (var adUnitId in adUnitIds) { CreateNativeAd(adUnitId); } } private void CreateNativeAd(string adUnitId) { if (_nativeAds.ContainsKey(adUnitId)) { LoggerUtils.Debug($"[Admob] Native Ad unit {adUnitId} already exists"); return; } LoadAd(adUnitId); _adRevenueCache[adUnitId] = 0; } public void LoadAd(string adUnitId) { LoggerUtils.Debug($"[Admob] Native Ad unit {adUnitId} load start"); NativeOverlayAd.Load(adUnitId, new AdRequest(), new NativeAdOptions(), (NativeOverlayAd ad, LoadAdError error) => { LoggerUtils.Debug($"[Admob] Native Ad unit {adUnitId} load end. {ad} error {error}"); if (error != null || ad == null) { if (!_retryCounters.TryAdd(adUnitId, 0)) { _retryCounters[adUnitId]++; } var retryDelay = Math.Pow(2, Math.Min(6, _retryCounters[adUnitId])); TimerUtils.Instance.DelayExecute((float)retryDelay, () => { LoadAd(adUnitId); }); LoggerUtils.Debug("[Admob] Native ad failed to load an ad with error : " + error + " \n retryDelay :" + retryDelay); return; } _retryCounters[adUnitId] = 0; var nativeEcpm = AdmobUtils.GetNativeEcpm(ad); _nativeAds[adUnitId] = ad; _adRevenueCache[adUnitId] = nativeEcpm; LoggerUtils.Debug($"Admob Native ad loaded with nativeEcpm = {nativeEcpm} response : " + ad.GetResponseInfo().ToString()); AdsKeyEvents.Instance.LogAdFPUEvents(AdsType.Native); ad.OnAdPaid += (AdValue adValue) => { LoggerUtils.Debug($"[Admob] Native ad paid {adValue.Value} {adValue.CurrencyCode}."); AdmobAdsManager.Instance.TrackAdImpression(ad.GetResponseInfo().GetLoadedAdapterResponseInfo(), adValue, AdsType.Native, adUnitId); }; ad.OnAdImpressionRecorded += () => { LoggerUtils.Debug("[Admob] Native ad recorded an impression."); }; ad.OnAdClicked += () => { LoggerUtils.Debug("[Admob] Native ad was clicked."); }; ad.OnAdFullScreenContentOpened += () => { LoggerUtils.Debug("[Admob] Native ad full screen content opened."); }; ad.OnAdFullScreenContentClosed += () => { LoggerUtils.Debug("[Admob] Native ad full screen content closed."); }; }); } // 显示价格最高的广告 public void ShowHighestPayingAd(NativeAdPosition position) { LoggerUtils.Debug($"[Admob] Native ad ShowHighestPayingAd {position}"); var highestPayingAdUnit = GetHighestPayingAdUnit(); LoggerUtils.Debug($"[Admob] Native ad ShowHighestPayingAd {position} , highestPayingAdUnit = {highestPayingAdUnit}"); if (!string.IsNullOrEmpty(highestPayingAdUnit)) { ShowAd(position, highestPayingAdUnit); } } // 显示特定广告位的广告 public void ShowAd(NativeAdPosition position, string adUnitId) { LoggerUtils.Debug($"[Admob] Native ad ShowAd start {adUnitId} , {position}"); if (_nativeAds.TryGetValue(adUnitId, out var ad)) { LoggerUtils.Debug($"[Admob] Native ad ShowAd end {adUnitId} , {position}"); // Define a native template style with a custom style. var style = position.NativeTemplateStyle ?? new NativeTemplateStyle() { TemplateId = NativeTemplateId.Medium, // TemplateId = "big" // MainBackgroundColor = Color.green, CallToActionText = new NativeTemplateTextStyle() { FontSize = 9, Style = NativeTemplateFontStyle.Bold } }; // Renders a native overlay ad at the default size // and anchored to the bottom of the screne. ad.RenderTemplate(style, new AdSize(position.Width, position.Height), position.X, position.Y); ad.Show(); } } // 检查特定广告位是否可用 public bool IsAdAvailable(string adUnitId) { return _nativeAds.TryGetValue(adUnitId, out _); } // 获取所有可用的广告位 public List GetAvailableAdUnits() { return _nativeAds.Select(kvp => kvp.Key).ToList(); } // 获取价格最高的广告位ID public string GetHighestPayingAdUnit() { string highestPayingAdUnit = null; double highestRevenue = -1; LoggerUtils.Debug($"[Admob] Native ad GetHighestPayingAdUnit {_adRevenueCache.Count}"); foreach (var kvp in _adRevenueCache) { var adUnitId = kvp.Key; var revenue = kvp.Value; // 确保广告确实已加载并且价格更高 if (IsAdAvailable(adUnitId) && revenue > highestRevenue) { highestRevenue = revenue; highestPayingAdUnit = adUnitId; } } return highestPayingAdUnit; } // 获取价格最高的广告收益信息 public double GetHighestPayingAdRevenue() { var highestPayingAdUnit = GetHighestPayingAdUnit(); if (!string.IsNullOrEmpty(highestPayingAdUnit) && _adRevenueCache.TryGetValue(highestPayingAdUnit, out var revenue)) { return revenue; } return 0; } // 清理资源 public void Destroy() { foreach (var ad in _nativeAds.Values) { ad.Destroy(); } _nativeAds.Clear(); _adRevenueCache.Clear(); } public void RemoveNative(string adUnitId) { if (adUnitId == null || string.IsNullOrEmpty(adUnitId)) { foreach (var nativeOverlayAd in _nativeAds) { nativeOverlayAd.Value.Hide(); LoadAd(nativeOverlayAd.Key); } return; } if (_nativeAds.TryGetValue(adUnitId, out var tempAd)) { tempAd.Hide(); LoadAd(adUnitId); } } } }