From 04c7bd4345b8e9c79a36172704cd0b1fdd898ad6 Mon Sep 17 00:00:00 2001 From: luojian Date: Mon, 1 Sep 2025 23:57:10 +0800 Subject: [PATCH] native --- Assets/Script/Common/IAdService.cs | 3 + .../AdmobAdsManager/AdmobNativeAdManager.cs | 195 +++++++++++++++++- 2 files changed, 189 insertions(+), 9 deletions(-) diff --git a/Assets/Script/Common/IAdService.cs b/Assets/Script/Common/IAdService.cs index b93deb6..8169e4a 100644 --- a/Assets/Script/Common/IAdService.cs +++ b/Assets/Script/Common/IAdService.cs @@ -1,4 +1,5 @@ using System; +using GoogleMobileAds.Api; using UnityEditor.Media; namespace WZ @@ -196,6 +197,8 @@ namespace WZ /// 广告高度 /// public int Height; + + public NativeTemplateStyle NativeTemplateStyle; } [System.Serializable] diff --git a/Assets/Script/SDKManager/AdsSDKManager/AdmobAdsManager/AdmobNativeAdManager.cs b/Assets/Script/SDKManager/AdsSDKManager/AdmobAdsManager/AdmobNativeAdManager.cs index db631f6..2121e2a 100644 --- a/Assets/Script/SDKManager/AdsSDKManager/AdmobAdsManager/AdmobNativeAdManager.cs +++ b/Assets/Script/SDKManager/AdsSDKManager/AdmobAdsManager/AdmobNativeAdManager.cs @@ -1,22 +1,199 @@ +using System; using System.Collections; using System.Collections.Generic; +using System.Linq; +using GoogleMobileAds.Api; using UnityEngine; namespace WZ -{ - public class AdmobNativeAdManager : MonoBehaviour +{ + public class AdmobNativeAdManager { - // Start is called before the first frame update - void Start() - { + 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); + } } - // Update is called once per frame - void Update() + 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) => + { + if (error != null || ad == null) + { + _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; + + LoggerUtils.Debug("Admob Native ad loaded with response : " + ad.GetResponseInfo().ToString()); + _nativeAds[adUnitId] = ad; + _adRevenueCache[adUnitId] = AdmobUtils.GetNativeEcpm(ad); + 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, + AdmobUtils.ParseResponseInfo(ad.GetResponseInfo())); + }; + + 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(); + } + } + + + // 检查特定广告位是否可用 + private 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 ad in _nativeAds.Values) + { + ad.Hide(); + } + + return; + } + + if (_nativeAds.TryGetValue(adUnitId, out var tempAd)) + { + tempAd.Hide(); + } } } -} - +} \ No newline at end of file