Trusted Arbiter 会比较已加载的 CloudX 出价与受支持的第三方出价,并返回选中的平台。从 Unity SDK 4.1.0 起可用(底层依赖 Android SDK 4.1.1 和 iOS SDK 3.4.1),支持 CloudX、Unity LevelPlay 和 PubMatic 出价输入。
请在 CloudXSdk.Initialize() 完成后(即收到 CloudXInitializationCallbacks.OnSdkInitializedEvent 事件之后)再调用 CloudXSdk.Arbiter()。在仲裁服务可用之前,SDK 会在传入的出价中回退选择可比较美元出价最高的平台。
基础 API
从已加载的广告创建出价候选项,然后传给 CloudXSdk.Arbiter()。
using System.Collections.Generic;
using CloudX;
using UnityEngine;
// cloudXAd 是 CloudX OnAdLoadSuccess 回调中的 CloudXAd 对象。
// 它的 AdValues 映射携带了服务器用于校验出价的受信任载荷键。
// levelPlayNetwork / levelPlayRevenue / levelPlayPrecision 来自 Unity LevelPlay 广告信息。
// pubMaticPrice 和 pubMaticPartner 来自 PubMatic/OpenWrap 出价对象。
var bids = new List<CloudXArbiterBid>
{
new CloudXArbiterBid.CloudX(cloudXAd),
new CloudXArbiterBid.LevelPlay(
NetworkName: levelPlayNetwork,
Revenue: levelPlayRevenue,
Precision: levelPlayPrecision),
new CloudXArbiterBid.PubMatic(
Price: pubMaticPrice,
PartnerName: pubMaticPartner),
};
CloudXSdk.Arbiter(bids, result =>
{
Debug.Log($"选中的平台: {result.Platform}");
});
CloudXArbiterBid.CloudX 接收 CloudX 加载回调中的 CloudXAd 对象。CloudXArbiterBid.LevelPlay 接收 Unity LevelPlay 广告信息值。CloudXArbiterBid.PubMatic 接收 PubMatic OpenWrap 出价价格和可选的合作伙伴名称。Extras 映射在 LevelPlay 和 PubMatic 出价中均为可选参数,PartnerName 在 PubMatic 出价中为可选参数。完成回调在主线程上执行,因此你可以直接在其中展示广告或更新 UI。
result.Platform 在选中平台时为 CloudXArbiterPlatform.CloudX、LevelPlay 或 PubMatic;当无法选出获胜平台时(例如未传入任何出价),则为 CloudXArbiterPlatform.None。结果还提供 result.Id(拍卖标识符)、result.BidId(获胜出价标识符,当平台为 None 时为 null)以及 result.Extras(获胜广告网络返回的附加元数据)。
分步示例:在 CloudX 与 LevelPlay 之间仲裁
本演练展示了应读取哪个 Unity LevelPlay 回调,以及应将哪些值传入 CloudXSdk.Arbiter()。示例使用插屏广告,但相同的字段映射适用于任何广告格式。
加载两个候选项
创建 LevelPlay 插屏广告,并为每个平台启动加载。请在加载之前订阅加载回调。var levelPlayAd = new LevelPlayInterstitialAd("YOUR_LEVELPLAY_AD_UNIT_ID");
levelPlayAd.OnAdLoaded += OnLevelPlayLoaded;
levelPlayAd.OnAdLoadFailed += OnLevelPlayLoadFailed;
levelPlayAd.LoadAd();
CloudXAdsCallbacks.Interstitial.OnAdLoadSuccess += OnCloudXLoaded;
CloudXSdk.LoadInterstitial("YOUR_CLOUDX_AD_UNIT_ID");
保存每个平台已加载的广告
LevelPlay 在其 OnAdLoaded 回调中提供 LevelPlayAdInfo;CloudX 在 OnAdLoadSuccess 中提供 CloudXAd。请保存两者——下一步会从中读取仲裁输入。private CloudXAd _cloudXAd;
private LevelPlayAdInfo _levelPlayInfo;
private void OnCloudXLoaded(CloudXAd ad) => _cloudXAd = ad;
private void OnLevelPlayLoaded(LevelPlayAdInfo info) => _levelPlayInfo = info;
将值映射为出价
从 LevelPlayAdInfo 读取 LevelPlay 字段,并传给 CloudXArbiterBid.LevelPlay。CloudX 出价直接接收 CloudXAd。LevelPlayAdInfo 字段 | 类型 | CloudXArbiterBid.LevelPlay 参数 |
|---|
adNetwork | string | NetworkName |
revenue | double? | Revenue(用 ?? 0 合并空值) |
precision | string | Precision |
var bids = new List<CloudXArbiterBid>
{
new CloudXArbiterBid.CloudX(_cloudXAd),
new CloudXArbiterBid.LevelPlay(
NetworkName: _levelPlayInfo.adNetwork, // LevelPlayAdInfo.adNetwork
Revenue: _levelPlayInfo.revenue ?? 0, // LevelPlayAdInfo.revenue 为 double?
Precision: _levelPlayInfo.precision), // LevelPlayAdInfo.precision
};
运行仲裁器
将出价连同完成回调传给 CloudXSdk.Arbiter()。回调在 Unity 主线程上执行。CloudXSdk.Arbiter(bids, OnArbiterCompleted);
展示获胜平台
根据 result.Platform 进行分支,展示获胜平台的广告。CloudXArbiterPlatform.None 表示未选出获胜平台——此时不展示广告,继续应用流程。private void OnArbiterCompleted(CloudXArbiterResult result)
{
switch (result.Platform)
{
case CloudXArbiterPlatform.CloudX:
CloudXSdk.ShowInterstitial("YOUR_CLOUDX_AD_UNIT_ID", "level_complete");
break;
case CloudXArbiterPlatform.LevelPlay:
levelPlayAd.ShowAd("level_complete");
break;
default:
break; // CloudXArbiterPlatform.None——无获胜平台;不展示广告
}
}
在 LevelPlay Unity SDK 8.x 中,LevelPlayAdInfo 使用 camelCase 字段(adNetwork、revenue、precision)。revenue 为 double?,因此在传给非空的 Revenue 参数时请使用 ?? 0 合并空值。
下方的 ArbiterInterstitialController 将上述步骤封装为一个可复用的组件,会在到达广告位之前提前准备好获胜平台。
插屏广告示例
这个插屏广告示例会在两个平台之间仲裁:CloudX 和 Unity LevelPlay。在到达广告位之前先准备好获胜平台:
- 并行加载 CloudX 和 LevelPlay。
- 等待两个平台都加载完成或加载失败。
- 只将已加载的候选项提交给 Trusted Arbiter。
- 缓存选中的平台。
- 到达广告位时,立即展示缓存的获胜广告。
如果两个平台都加载失败,开始新的加载周期。如果到达广告位时还没有准备好获胜平台,则继续应用流程,不展示广告。
ArbiterInterstitialController.cs
using System.Collections.Generic;
using CloudX;
using UnityEngine;
/// <summary>
/// 提前准备好 Trusted Arbiter 的获胜平台,以便在到达广告位时立即展示插屏广告。
///
/// 并行加载 CloudX 和 LevelPlay 插屏广告,等待两者都加载完成或加载失败,
/// 将已加载的候选项提交给 CloudXSdk.Arbiter,并将选中的 CloudXArbiterPlatform
/// 缓存到 _nextWinner 中。
/// </summary>
public class ArbiterInterstitialController : MonoBehaviour
{
private const string CloudXAdUnitId = "interstitial_main";
// 当 LevelPlay Unity SDK 报告插屏广告已加载时,由宿主设置。
public string LevelPlayNetwork;
public double LevelPlayRevenue;
public string LevelPlayPrecision;
// 当仲裁器为下一次展示选出平台后调用。
public System.Action<CloudXArbiterPlatform> OnWinnerPrepared;
private CloudXAd _cloudXAd;
private bool _cloudXLoadDone;
private bool _levelPlayLoaded;
private bool _levelPlayLoadDone;
private CloudXArbiterPlatform? _nextWinner;
private void OnEnable()
{
CloudXAdsCallbacks.Interstitial.OnAdLoadSuccess += OnCloudXLoaded;
CloudXAdsCallbacks.Interstitial.OnAdLoadFailed += OnCloudXLoadFailed;
CloudXAdsCallbacks.Interstitial.OnAdHidden += OnCloudXHidden;
CloudXAdsCallbacks.Interstitial.OnAdShowFailed += OnCloudXShowFailed;
}
private void OnDisable()
{
CloudXAdsCallbacks.Interstitial.OnAdLoadSuccess -= OnCloudXLoaded;
CloudXAdsCallbacks.Interstitial.OnAdLoadFailed -= OnCloudXLoadFailed;
CloudXAdsCallbacks.Interstitial.OnAdHidden -= OnCloudXHidden;
CloudXAdsCallbacks.Interstitial.OnAdShowFailed -= OnCloudXShowFailed;
}
/// <summary>为每个当前没有缓存广告的平台启动加载。</summary>
public void LoadMissingAds()
{
if (_cloudXAd == null) CloudXSdk.LoadInterstitial(CloudXAdUnitId);
if (!_levelPlayLoaded) LoadLevelPlayInterstitial();
}
/// <summary>
/// 展示已准备好的获胜广告,仅当确实发起了展示调用时返回 true。
///
/// 当没有准备好获胜平台或缓存的广告已不可用时返回 false,
/// 此时会启动一次新的加载周期。
/// </summary>
public bool ShowAtPlacement(string placement)
{
switch (_nextWinner)
{
case CloudXArbiterPlatform.CloudX:
return ShowCloudX(placement);
case CloudXArbiterPlatform.LevelPlay:
return ShowLevelPlay(placement);
default:
return false;
}
}
/// <summary>
/// 在两个平台都完成后运行仲裁器,然后缓存获胜平台。
///
/// 在两个加载都完成之前提前返回。如果两个平台都没有加载成功,则重启加载周期;
/// 否则将已加载的候选项提交给 CloudXSdk.Arbiter。
/// </summary>
private void MaybePrepareWinner()
{
if (!_cloudXLoadDone || !_levelPlayLoadDone) return;
if (_cloudXAd == null && !_levelPlayLoaded)
{
_cloudXLoadDone = false;
_levelPlayLoadDone = false;
LoadMissingAds();
return;
}
var bids = new List<CloudXArbiterBid>();
if (_cloudXAd != null)
{
bids.Add(new CloudXArbiterBid.CloudX(_cloudXAd));
}
if (_levelPlayLoaded)
{
bids.Add(new CloudXArbiterBid.LevelPlay(
NetworkName: LevelPlayNetwork,
Revenue: LevelPlayRevenue,
Precision: LevelPlayPrecision));
}
CloudXSdk.Arbiter(bids, result =>
{
_nextWinner = result.Platform;
OnWinnerPrepared?.Invoke(result.Platform);
});
}
private bool ShowCloudX(string placement)
{
if (CloudXSdk.IsInterstitialReady(CloudXAdUnitId))
{
CloudXSdk.ShowInterstitial(CloudXAdUnitId, placement);
return true;
}
ClearCloudXAndLoadMissingAds();
return false;
}
private bool ShowLevelPlay(string placement)
{
if (IsLevelPlayInterstitialReady())
{
ShowLevelPlayInterstitial(placement);
return true;
}
ClearLevelPlayAndLoadMissingAds();
return false;
}
private void OnCloudXLoaded(CloudXAd ad)
{
_cloudXAd = ad;
_cloudXLoadDone = true;
MaybePrepareWinner();
}
private void OnCloudXLoadFailed(string adUnitId, CloudXError error)
{
_cloudXAd = null;
_cloudXLoadDone = true;
MaybePrepareWinner();
}
private void OnCloudXHidden(CloudXAd ad) => ClearCloudXAndLoadMissingAds();
private void OnCloudXShowFailed(CloudXAd ad, CloudXError error) => ClearCloudXAndLoadMissingAds();
private void ClearCloudXAndLoadMissingAds()
{
_cloudXAd = null;
_cloudXLoadDone = false;
_nextWinner = null;
LoadMissingAds();
}
private void ClearLevelPlayAndLoadMissingAds()
{
_levelPlayLoaded = false;
_levelPlayLoadDone = false;
_nextWinner = null;
LoadMissingAds();
}
/*
* 下面的成员封装了 LevelPlay Unity SDK。请用你集成的 LevelPlay SDK 调用替换其方法体,
* 并将其加载回调接入上面的字段:加载成功时,设置 _levelPlayLoaded = true 及各个
* LevelPlay* 值,然后设置 _levelPlayLoadDone = true 并调用 MaybePrepareWinner();
* 加载失败时,设置 _levelPlayLoaded = false、_levelPlayLoadDone = true,
* 并调用 MaybePrepareWinner()。广告关闭或展示失败时,调用
* ClearLevelPlayAndLoadMissingAds() 以丢弃已消耗的广告并开始新的加载周期。
*/
private void LoadLevelPlayInterstitial() { /* LevelPlay.LoadInterstitial(...) */ }
private bool IsLevelPlayInterstitialReady() => _levelPlayLoaded;
private void ShowLevelPlayInterstitial(string placement) { /* LevelPlay.ShowInterstitial(...) */ }
}
ShowAtPlacement() 仅当确实发起了展示调用时返回 true。在 LevelPlay 广告保持加载状态期间,请持续更新缓存的 LevelPlay 候选项值。
对于 PubMatic OpenWrap,使用 new CloudXArbiterBid.PubMatic(price, partnerName) 创建第三方出价。如果仲裁服务不可用,SDK 会在传入的受支持出价输入中回退选择可比较美元出价最高的平台。