First Look
让 CloudX 优先填充广告位,然后回退到您现有的聚合设置
First Look 让 CloudX 优先获得广告位填充机会,同时保留您现有的聚合设置作为回退路径。建议先从一个广告位开始,验证加载和展示行为后,再扩展到更多广告位。
此示例通过 Google Mobile Ads Unity 插件 使用 AdMob 插屏广告作为回退。相同模式也适用于其他回退聚合平台:先加载 CloudX;只有当 CloudX 未加载成功时才加载回退广告;当两个来源都未准备好时,让游戏流程继续。
FirstLookInterstitialController.cs
using System;
using CloudX;
using GoogleMobileAds.Api;
public sealed class FirstLookInterstitialController : IDisposable
{
public enum Source
{
CloudX,
AdMob,
}
public event Action<Source> AdLoaded;
public event Action<Source, string> AdLoadFailed;
public event Action<Source> AdShown;
public event Action<Source, string> AdShowFailed;
public event Action<Source> AdClosed;
public event Action<Source> AdClicked;
private readonly string cloudXAdUnitId;
private readonly string adMobAdUnitId;
private InterstitialAd adMobInterstitial;
private bool isLoadingCloudX;
private bool isLoadingAdMob;
private bool isDisposed;
public FirstLookInterstitialController(
string cloudXAdUnitId,
string adMobAdUnitId)
{
this.cloudXAdUnitId = cloudXAdUnitId;
this.adMobAdUnitId = adMobAdUnitId;
CloudXAdsCallbacks.Interstitial.OnAdLoadSuccess += OnCloudXLoaded;
CloudXAdsCallbacks.Interstitial.OnAdLoadFailed += OnCloudXLoadFailed;
CloudXAdsCallbacks.Interstitial.OnAdShowSuccess += OnCloudXShown;
CloudXAdsCallbacks.Interstitial.OnAdShowFailed += OnCloudXShowFailed;
CloudXAdsCallbacks.Interstitial.OnAdHidden += OnCloudXClosed;
CloudXAdsCallbacks.Interstitial.OnAdClicked += OnCloudXClicked;
}
public void Load()
{
if (isDisposed ||
isLoadingCloudX ||
isLoadingAdMob ||
CloudXSdk.IsInterstitialReady(cloudXAdUnitId) ||
(adMobInterstitial != null && adMobInterstitial.CanShowAd()))
{
return;
}
isLoadingCloudX = true;
CloudXSdk.LoadInterstitial(cloudXAdUnitId);
}
public bool Show()
{
if (isDisposed)
{
return false;
}
if (CloudXSdk.IsInterstitialReady(cloudXAdUnitId))
{
CloudXSdk.ShowInterstitial(cloudXAdUnitId);
return true;
}
return ShowAdMobFallback();
}
public void Dispose()
{
if (isDisposed)
{
return;
}
isDisposed = true;
CloudXAdsCallbacks.Interstitial.OnAdLoadSuccess -= OnCloudXLoaded;
CloudXAdsCallbacks.Interstitial.OnAdLoadFailed -= OnCloudXLoadFailed;
CloudXAdsCallbacks.Interstitial.OnAdShowSuccess -= OnCloudXShown;
CloudXAdsCallbacks.Interstitial.OnAdShowFailed -= OnCloudXShowFailed;
CloudXAdsCallbacks.Interstitial.OnAdHidden -= OnCloudXClosed;
CloudXAdsCallbacks.Interstitial.OnAdClicked -= OnCloudXClicked;
CloudXSdk.DestroyInterstitial(cloudXAdUnitId);
DestroyAdMobInterstitial();
}
private void OnCloudXLoaded(CloudXAd ad)
{
if (ad.AdUnitId != cloudXAdUnitId)
{
return;
}
isLoadingCloudX = false;
AdLoaded?.Invoke(Source.CloudX);
}
private void OnCloudXLoadFailed(string adUnitId, CloudXError _)
{
if (adUnitId != cloudXAdUnitId)
{
return;
}
isLoadingCloudX = false;
LoadAdMobFallback();
}
private void OnCloudXShown(CloudXAd ad)
{
if (ad.AdUnitId == cloudXAdUnitId)
{
AdShown?.Invoke(Source.CloudX);
}
}
private void OnCloudXShowFailed(CloudXAd ad, CloudXError error)
{
if (ad.AdUnitId != cloudXAdUnitId)
{
return;
}
if (!ShowAdMobFallback())
{
AdShowFailed?.Invoke(Source.CloudX, error.Message);
}
}
private void OnCloudXClosed(CloudXAd ad)
{
if (ad.AdUnitId == cloudXAdUnitId)
{
AdClosed?.Invoke(Source.CloudX);
}
}
private void OnCloudXClicked(CloudXAd ad)
{
if (ad.AdUnitId == cloudXAdUnitId)
{
AdClicked?.Invoke(Source.CloudX);
}
}
private void LoadAdMobFallback()
{
if (isDisposed ||
isLoadingAdMob ||
(adMobInterstitial != null && adMobInterstitial.CanShowAd()))
{
return;
}
isLoadingAdMob = true;
DestroyAdMobInterstitial();
InterstitialAd.Load(
adMobAdUnitId,
new AdRequest(),
(ad, error) =>
{
isLoadingAdMob = false;
if (isDisposed)
{
ad?.Destroy();
return;
}
if (error != null || ad == null)
{
AdLoadFailed?.Invoke(
Source.AdMob,
error?.GetMessage() ?? "AdMob returned no ad");
return;
}
adMobInterstitial = ad;
RegisterAdMobEvents(ad);
AdLoaded?.Invoke(Source.AdMob);
});
}
private bool ShowAdMobFallback()
{
if (adMobInterstitial == null || !adMobInterstitial.CanShowAd())
{
return false;
}
adMobInterstitial.Show();
return true;
}
private void RegisterAdMobEvents(InterstitialAd ad)
{
ad.OnAdFullScreenContentOpened += () =>
AdShown?.Invoke(Source.AdMob);
ad.OnAdFullScreenContentClosed += () =>
{
DestroyAdMobInterstitial();
AdClosed?.Invoke(Source.AdMob);
};
ad.OnAdFullScreenContentFailed += error =>
{
DestroyAdMobInterstitial();
AdShowFailed?.Invoke(Source.AdMob, error.GetMessage());
};
ad.OnAdClicked += () =>
AdClicked?.Invoke(Source.AdMob);
}
private void DestroyAdMobInterstitial()
{
adMobInterstitial?.Destroy();
adMobInterstitial = null;
}
}在广告位触发时调用 Show()。如果返回 false,表示 CloudX 和回退广告都没有准备好,此时应继续游戏流程,不展示广告。
if (!firstLookInterstitial.Show())
{
ContinueToNextScene();
}广告展示、关闭或最终失败后,请在游戏准备好下一次广告位机会时再次调用 Load()。拥有此控制器的 MonoBehaviour 销毁时,请调用 Dispose()。