Unity集成AdMob遇高请求低展示问题求助(插屏/激励广告)
AdMob广告集成问题排查(Bubble Shooter Infinity)
我在Unity开发的游戏《Bubble Shooter Infinity》中集成了AdMob激励广告,虽然应用状态显示"Ready",但印度、美国、巴西等多个地区出现了高请求、低展示的异常情况。以巴西地区2025/07/01的数据为例:
- 请求量:307
- 展示量:16
- 匹配率:100.00%
- eCPM:US$4.77
- 收益:US$0.08
已排查项
- 应用已通过AdMob审核,状态为Ready
- 仅使用激励广告(Rewarded Ads)和插屏广告(Interstitial Ads)两种格式
- 各地区匹配率普遍较高(约98%)
- 请求量持续增长,但展示量始终处于低位
- eCPM数值偏低
- 采用Unity + GoogleMobileAds插件的标准集成方式
问题咨询
- 为何匹配率良好的情况下,还会出现高请求低展示?
- 问题是否出在AdMob填充率、广告可用性或投放时机上?
- 是否需要添加插屏或横幅广告来提升填充率?
- 是否需要积累更多流量,才能提升美国、埃及等地区的填充率?
广告触发逻辑
- 插屏广告:玩家每完成2关后展示
- 激励广告:玩家分数翻倍时展示
测试环境中能正常看到广告,但正式上线后出现上述问题。
相关代码
AdsManager.cs
using System; using System.Collections.Generic; using BubbleShooterGameToolkit.Scripts.Ads.AdUnits; using BubbleShooterGameToolkit.Scripts.CommonUI.Popups; using BubbleShooterGameToolkit.Scripts.Services; using BubbleShooterGameToolkit.Scripts.Settings; using BubbleShooterGameToolkit.Scripts.System; using UnityEngine; namespace BubbleShooterGameToolkit.Scripts.Gameplay.Managers { public class AdsManager : SingletonBehaviour<AdsManager> { [SerializeField] private List<AdSetting> adList = new(); [SerializeField] private List<AdUnit> adUnits = new(); private EPlatforms platforms; public override void Awake() { base.Awake(); platforms = GetPlatform(); var adElements = Resources.Load<AdsSettings>("Settings/AdsSettings").adProfiles; foreach (var t in adElements) { if (t.platforms == platforms && t.enable) { if (Application.isEditor && !t.testInEditor) { continue; } adList.Add(t); foreach (var adElement in t.adElements) { var adUnit = new AdUnit { PlacementId = adElement.placementId, AdReference = adElement.adReference, AdsHandler = t.adsHandler }; adUnit.OnInitialized = placementId => adUnit.Load(); adUnits.Add(adUnit); } t.adsHandler.Init(t.appId, false, new AdsListener(adUnits)); } } } private void OnEnable() { Popup.OnOpenPopup += OnOpenPopup; Popup.OnClosePopup += OnClosePopup; } private void OnDisable() { Popup.OnOpenPopup -= OnOpenPopup; Popup.OnClosePopup -= OnClosePopup; } private EPlatforms GetPlatform() { #if UNITY_ANDROID return EPlatforms.Android; #elif UNITY_IOS return EPlatforms.IOS; #elif UNITY_WEBGL return EPlatforms.WebGL; #else return EPlatforms.Windows; #endif } private void OnOpenPopup(Popup popup) { OnPopupTrigger(popup, true); } private void OnClosePopup(Popup popup) { OnPopupTrigger(popup, false); } private void OnPopupTrigger(Popup popup, bool open) { foreach (var ad in adList) { foreach (var adElement in ad.adElements) { var adUnit = adUnits.Find(i => i.AdReference == adElement.adReference); if (!adUnit.IsAvailable()) { adUnit.Load(); continue; } if (((open && adElement.popup.showOnOpen) || (!open && adElement.popup.showOnClose)) && popup.GetType() == adElement.popup.popup.GetType()) { if (LevelManager.instance.CurrentLevel % 2 == 0) { adUnit.Load(); adUnit.Show(); Debug.Log("IS ads loded" + adUnit.Loaded); return; } } } } } public void ShowAdByType(AdReference adRef, Action<string> shown) { if (NoAdsManager.IsNoAdsPurchased) { shown?.Invoke(string.Empty); return; } foreach (var adUnit in adUnits) { if (adUnit.AdReference == adRef && adUnit.IsAvailable()) { adUnit.OnShown = shown; adUnit.Load(); adUnit.Show(); return; } } } public bool IsRewardedAvailable(AdReference adRef) { Debug.LogError("add Check Was Called"); foreach (var adUnit in adUnits) { Debug.LogError("check count"); if (adUnit.AdReference == adRef) { Debug.LogError("was in check"); if (NoAdsManager.IsNoAdsPurchased) { return false; } if (adUnit.IsAvailable()) { Debug.LogError("is Add unit avalable " + adUnit.AdsHandler.name + " " + adUnit.IsAvailable()); return adUnit.IsAvailable(); } } } return false; } } }
AdmobHandler.cs
using BubbleShooterGameToolkit.Scripts.Ads.AdUnits; using UnityEngine; #if ADMOB using GoogleMobileAds.Api; #endif namespace BubbleShooterGameToolkit.Scripts.Ads.Networks { [CreateAssetMenu(fileName = "AdmobHandler", menuName = "BubbleShooterGameToolkit/Ads/AdmobHandler")] public class AdmobHandler : AdsHandlerBase { private IAdsListener _listener; #if ADMOB private InterstitialAd _interstitialAd; private RewardedAd _rewardedAd; #endif public override void Init(string _id, bool adSettingTestMode, IAdsListener listener) { #if ADMOB _listener = listener; MobileAds.RaiseAdEventsOnUnityMainThread = true; MobileAds.Initialize(initstatus => { if (initstatus == null) { Debug.LogError("Google Mobile Ads initialization failed."); return; } // If you use mediation, you can check the status of each adapter. var adapterStatusMap = initstatus.getAdapterStatusMap(); if (adapterStatusMap != null) { foreach (var item in adapterStatusMap) { Debug.Log(string.Format("Adapter {0} is {1}", item.Key, item.Value.InitializationState)); } } Debug.Log("Google Mobile Ads initialization complete."); _listener?.OnAdsInitialized(); }); #endif } public override void Show(AdUnit adUnit) { #if ADMOB _listener?.Show(adUnit); if (adUnit.AdReference.adType == EAdType.Interstitial) { if (_interstitialAd != null && _interstitialAd.CanShowAd()) { Debug.Log("Showing interstitial ad."); _interstitialAd.Show(); } else { Debug.LogError("Interstitial ad is not ready yet."); } } else if (adUnit.AdReference.adType == EAdType.Rewarded) { if (_rewardedAd != null && _rewardedAd.CanShowAd()) { _rewardedAd.Show(reward => { Debug.Log(string.Format("Rewarded ad granted a reward: {0} {1}", reward.Amount, reward.Type)); }); } else { Debug.LogError("Rewarded ad is not ready yet."); } } #endif } public override void Load(AdUnit adUnit) { #if ADMOB var adRequest = new AdRequest(); if (adUnit.AdReference.adType == EAdType.Interstitial) { InterstitialAd.Load(adUnit.PlacementId, adRequest, (ad, error) => { if (error != null) { Debug.LogError("Interstitial ad failed to load an ad with error : " + error); _listener.OnAdsLoadFailed(); return; } if (ad == null) { Debug.LogError("Unexpected error: Interstitial load event fired with null ad and null error."); _listener.OnAdsLoadFailed(); return; } _interstitialAd = ad; Debug.Log("Interstitial ad loaded with response : " + ad.GetResponseInfo()); ad.OnAdFullScreenContentClosed += () => { _listener.OnAdsShowComplete(); _interstitialAd = null; Load(adUnit); }; ad.OnAdFullScreenContentFailed += (AdError error) => { Debug.LogError("Interstitial ad failed to show: " + error); _listener.OnAdsShowFailed(); _interstitialAd = null; Load(adUnit); }; _listener?.OnAdsLoaded(adUnit.PlacementId); }); } else if (adUnit.AdReference.adType == EAdType.Rewarded) { RewardedAd.Load(adUnit.PlacementId, adRequest, (ad, error) => { if (error != null) { Debug.LogError("Rewarded ad failed to load an ad with error : " + error); _listener.OnAdsLoadFailed(); return; } if (ad == null) { Debug.LogError("Unexpected error: Rewarded load event fired with null ad and null error."); _listener.OnAdsLoadFailed(); return; } _rewardedAd = ad; ad.OnAdFullScreenContentClosed += () => { _listener.OnAdsShowComplete(); _rewardedAd = null; Load(adUnit); }; ad.OnAdFullScreenContentFailed += (AdError error) => { Debug.LogError("Rewarded ad failed to show: " + error); _listener.OnAdsShowFailed(); _rewardedAd = null; Load(adUnit); }; Debug.Log("Rewarded ad loaded with response : " + ad.GetResponseInfo()); _listener?.OnAdsLoaded(adUnit.PlacementId); }); } #endif } public override bool IsAvailable(AdUnit adUnit) { #if ADMOB if (adUnit.AdReference.adType == EAdType.Interstitial) return _interstitialAd != null && _interstitialAd.CanShowAd(); else if (adUnit.AdReference.adType == EAdType.Rewarded) return _rewardedAd != null && _rewardedAd.CanShowAd(); #endif return false; } } }
注意:测试时我总能正常看到插屏和激励广告
相关截图



内容的提问来源于stack exchange,提问作者Vignesh
相关产品推荐
相关产品推荐

