CloudX Unity SDK
CloudX Unity SDK 使您能够在 iOS 和 Android 上通过横幅、MREC、插屏和激励广告实现 Unity 游戏变现。
CloudX Unity SDK 以 .unitypackage 文件形式分发。
- 从 GitHub Releases 下载最新的
CloudXSdk-3.0.0.unitypackage
- 在 Unity 中,转到 Assets > Import Package > Custom Package
- 选择下载的
.unitypackage 文件
- 提示时导入所有资源
External Dependency Manager 将自动解析 Android 和 iOS 依赖。
广告网络适配器
CloudX SDK 需要广告网络适配器来投放广告。适配器是可选的,可以根据您要支持的广告网络启用。
启用适配器
打开 Assets/CloudXSdk/Editor/CloudXDependencies.xml 并取消注释您需要的适配器:
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<repositories>
<repository>https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea</repository>
</repositories>
<!-- CloudX 核心 SDK -->
<androidPackage spec="io.cloudx:sdk:3.0.0"/>
<!-- 可选:CloudX 适配器(根据需要取消注释) -->
<androidPackage spec="io.cloudx:adapter-meta:3.0.0"/>
<androidPackage spec="io.cloudx:adapter-vungle:3.0.0"/>
<androidPackage spec="io.cloudx:adapter-inmobi:3.0.0"/>
<androidPackage spec="io.cloudx:adapter-mintegral:3.0.0"/>
<androidPackage spec="io.cloudx:adapter-unityads:3.0.0"/>
</androidPackages>
<iosPods>
<!-- CloudX 核心 SDK -->
<iosPod name="CloudXCore" version="2.2.8" minTargetSdk="13.0"/>
<iosPod name="CloudXRenderer" version="2.2.8" minTargetSdk="13.0"/>
<!-- 可选:CloudX 适配器(根据需要取消注释) -->
<iosPod name="CloudXMetaAdapter" version="2.2.8" minTargetSdk="13.0"/>
<iosPod name="CloudXVungleAdapter" version="2.2.8" minTargetSdk="13.0"/>
<iosPod name="CloudXInMobiAdapter" version="2.2.8" minTargetSdk="13.0"/>
<iosPod name="CloudXMintegralAdapter" version="2.2.8" minTargetSdk="13.0"/>
<iosPod name="CloudXUnityAdsAdapter" version="2.2.8" minTargetSdk="13.0"/>
</iosPods>
</dependencies>
修改文件后,转到 Assets > External Dependency Manager > Android Resolver > Force Resolve 下载新依赖。
可用适配器
| 适配器 | 包 | 描述 |
|---|
| Meta Audience Network | io.cloudx:adapter-meta | Facebook/Meta 广告 |
| Vungle | io.cloudx:adapter-vungle | Vungle 视频广告 |
| InMobi | io.cloudx:adapter-inmobi | InMobi 广告 |
| Mintegral | io.cloudx:adapter-mintegral | Mintegral 广告 |
| Unity Ads | io.cloudx:adapter-unityads | Unity Ads 横幅、插屏和激励广告 |
初始化
在加载任何广告之前初始化 SDK。您可以在初始化之前选择性地配置用户和应用属性。
using CloudX;
using UnityEngine;
public class MyGameManager : MonoBehaviour
{
void Start()
{
InitializeCloudX();
}
void InitializeCloudX()
{
// 初始化前配置(可选)
CloudXSdk.SetHashedUserId("hashed-user-id");
CloudXSdk.SetUserKeyValue("user_level", "premium");
CloudXSdk.SetAppKeyValue("app_version", "1.0.0");
// 在初始化之前订阅回调
CloudXInitializationCallbacks.OnSdkInitializedEvent += OnSdkInitialized;
CloudXInitializationCallbacks.OnSdkInitializationFailedEvent += OnSdkInitializationFailed;
// 初始化 SDK
var config = CloudXInitializationConfiguration.Create("YOUR_APP_KEY").Build();
CloudXSdk.Initialize(config);
}
private void OnSdkInitialized(CloudXSdkConfiguration config)
{
Debug.Log("CloudX SDK 初始化成功");
// 现在可以加载广告
}
private void OnSdkInitializationFailed(CloudXError error)
{
Debug.LogError($"SDK 初始化失败: {error}");
}
}
在调用 Initialize() 之前订阅 CloudXInitializationCallbacks 事件以接收初始化结果。
广告集成
横幅广告
具有自动刷新功能的标准横幅广告。
using CloudX;
using UnityEngine;
public class BannerExample : MonoBehaviour
{
private const string BannerAdUnitId = "banner_main";
void Start()
{
// 订阅回调
CloudXAdsCallbacks.Banner.OnAdLoadSuccess += OnBannerLoaded;
CloudXAdsCallbacks.Banner.OnAdLoadFailed += OnBannerLoadFailed;
CloudXAdsCallbacks.Banner.OnAdClicked += OnBannerClicked;
CloudXAdsCallbacks.Banner.OnAdRevenuePaid += OnBannerRevenuePaid;
// 创建、加载并显示横幅
var config = new CloudXAdViewConfiguration(CloudXAdViewConfiguration.AdViewPosition.BottomCenter);
CloudXSdk.CreateBanner(BannerAdUnitId, config);
CloudXSdk.LoadBanner(BannerAdUnitId);
CloudXSdk.ShowBanner(BannerAdUnitId);
}
void OnApplicationFocus(bool hasFocus)
{
if (hasFocus)
{
CloudXSdk.ShowBanner(BannerAdUnitId);
}
else
{
CloudXSdk.HideBanner(BannerAdUnitId);
}
}
private void OnBannerLoaded(CloudXAd ad)
{
Debug.Log($"横幅已加载: {ad.AdUnitId}");
}
private void OnBannerLoadFailed(string adUnitId, CloudXError error)
{
Debug.LogError($"横幅加载失败: {adUnitId} - {error}");
}
private void OnBannerClicked(CloudXAd ad)
{
Debug.Log($"横幅被点击: {ad.AdUnitId}");
}
private void OnBannerRevenuePaid(CloudXAd ad)
{
Debug.Log($"横幅收入: ${ad.Revenue},来自 {ad.NetworkName}");
}
}
自动刷新控制:
横幅广告默认自动刷新。手动控制刷新:
CloudXSdk.StopBannerAutoRefresh(BannerAdUnitId); // 停止自动刷新
CloudXSdk.LoadBanner(BannerAdUnitId); // 手动加载
CloudXSdk.StartBannerAutoRefresh(BannerAdUnitId); // 重新启用自动刷新
广告位和自定义数据:
您可以为横幅广告设置广告位和自定义数据:
CloudXSdk.SetBannerPlacement(BannerAdUnitId, "home_screen");
CloudXSdk.SetBannerCustomData(BannerAdUnitId, "custom_value");
从 2.2.6 开始,如果希望首次 Banner 请求就带上 placement 和 customData,请在调用 CreateBanner(...) 之前先调用 SetBannerPlacement(...) 和 SetBannerCustomData(...)。
MREC 广告 (300x250)
中等矩形广告与横幅的工作方式相同,但尺寸更大。
using CloudX;
using UnityEngine;
public class MrecExample : MonoBehaviour
{
private const string MrecAdUnitId = "mrec_main";
void Start()
{
// 订阅回调
CloudXAdsCallbacks.Mrec.OnAdLoadSuccess += OnMrecLoaded;
CloudXAdsCallbacks.Mrec.OnAdLoadFailed += OnMrecLoadFailed;
CloudXAdsCallbacks.Mrec.OnAdClicked += OnMrecClicked;
CloudXAdsCallbacks.Mrec.OnAdRevenuePaid += OnMrecRevenuePaid;
// 创建、加载并显示 MREC
var config = new CloudXAdViewConfiguration(CloudXAdViewConfiguration.AdViewPosition.Centered);
CloudXSdk.CreateMrec(MrecAdUnitId, config);
CloudXSdk.LoadMrec(MrecAdUnitId);
CloudXSdk.ShowMrec(MrecAdUnitId);
}
void OnApplicationFocus(bool hasFocus)
{
if (hasFocus)
{
CloudXSdk.ShowMrec(MrecAdUnitId);
}
else
{
CloudXSdk.HideMrec(MrecAdUnitId);
}
}
private void OnMrecLoaded(CloudXAd ad)
{
Debug.Log($"MREC 已加载: {ad.AdUnitId}");
}
private void OnMrecLoadFailed(string adUnitId, CloudXError error)
{
Debug.LogError($"MREC 加载失败: {adUnitId} - {error}");
}
private void OnMrecClicked(CloudXAd ad)
{
Debug.Log($"MREC 被点击: {ad.AdUnitId}");
}
private void OnMrecRevenuePaid(CloudXAd ad)
{
Debug.Log($"MREC 收入: ${ad.Revenue},来自 {ad.NetworkName}");
}
}
自动刷新控制:
MREC 广告也默认自动刷新。使用与横幅相同的刷新控制方法:
CloudXSdk.StopMrecAutoRefresh(MrecAdUnitId);
CloudXSdk.LoadMrec(MrecAdUnitId);
CloudXSdk.StartMrecAutoRefresh(MrecAdUnitId);
广告位和自定义数据:
您可以为 MREC 广告设置广告位和自定义数据:
CloudXSdk.SetMrecPlacement(MrecAdUnitId, "game_over_screen");
CloudXSdk.SetMrecCustomData(MrecAdUnitId, "custom_value");
从 2.2.6 开始,如果希望首次 MREC 请求就带上 placement 和 customData,请在调用 CreateMrec(...) 之前先调用 SetMrecPlacement(...) 和 SetMrecCustomData(...)。
插屏广告
在内容过渡之间显示的全屏广告。
using CloudX;
using UnityEngine;
public class InterstitialExample : MonoBehaviour
{
private const string InterstitialAdUnitId = "interstitial_main";
void Start()
{
// 订阅回调
CloudXAdsCallbacks.Interstitial.OnAdLoadSuccess += OnInterstitialLoaded;
CloudXAdsCallbacks.Interstitial.OnAdLoadFailed += OnInterstitialLoadFailed;
CloudXAdsCallbacks.Interstitial.OnAdShowSuccess += OnInterstitialShown;
CloudXAdsCallbacks.Interstitial.OnAdShowFailed += OnInterstitialShowFailed;
CloudXAdsCallbacks.Interstitial.OnAdHidden += OnInterstitialHidden;
CloudXAdsCallbacks.Interstitial.OnAdClicked += OnInterstitialClicked;
CloudXAdsCallbacks.Interstitial.OnAdRevenuePaid += OnInterstitialRevenuePaid;
// 加载插屏
CloudXSdk.LoadInterstitial(InterstitialAdUnitId);
}
public void ShowInterstitial()
{
if (CloudXSdk.IsInterstitialReady(InterstitialAdUnitId))
{
// 显示时可附带广告位和自定义数据
CloudXSdk.ShowInterstitial(InterstitialAdUnitId, "level_complete", "custom_data");
}
else
{
Debug.LogWarning("插屏尚未准备好");
}
}
private void OnInterstitialLoaded(CloudXAd ad)
{
Debug.Log($"插屏已加载: {ad.AdUnitId}");
}
private void OnInterstitialLoadFailed(string adUnitId, CloudXError error)
{
Debug.LogError($"插屏加载失败: {adUnitId} - {error}");
}
private void OnInterstitialShown(CloudXAd ad)
{
Debug.Log($"插屏已展示: {ad.AdUnitId}");
}
private void OnInterstitialShowFailed(CloudXAd ad, CloudXError error)
{
Debug.LogError($"插屏展示失败: {ad.AdUnitId} - {error}");
// 为下次重新加载
CloudXSdk.LoadInterstitial(InterstitialAdUnitId);
}
private void OnInterstitialHidden(CloudXAd ad)
{
Debug.Log($"插屏已隐藏: {ad.AdUnitId}");
// 为下次重新加载
CloudXSdk.LoadInterstitial(InterstitialAdUnitId);
}
private void OnInterstitialClicked(CloudXAd ad)
{
Debug.Log($"插屏被点击: {ad.AdUnitId}");
}
private void OnInterstitialRevenuePaid(CloudXAd ad)
{
Debug.Log($"插屏收入: ${ad.Revenue},来自 {ad.NetworkName}");
}
}
激励广告
奖励用户观看视频广告。
using CloudX;
using UnityEngine;
public class RewardedExample : MonoBehaviour
{
private const string RewardedAdUnitId = "rewarded_main";
void Start()
{
// 订阅回调
CloudXAdsCallbacks.Rewarded.OnAdLoadSuccess += OnRewardedLoaded;
CloudXAdsCallbacks.Rewarded.OnAdLoadFailed += OnRewardedLoadFailed;
CloudXAdsCallbacks.Rewarded.OnAdShowSuccess += OnRewardedShown;
CloudXAdsCallbacks.Rewarded.OnAdShowFailed += OnRewardedShowFailed;
CloudXAdsCallbacks.Rewarded.OnAdHidden += OnRewardedHidden;
CloudXAdsCallbacks.Rewarded.OnAdClicked += OnRewardedClicked;
CloudXAdsCallbacks.Rewarded.OnAdRewarded += OnUserRewarded;
CloudXAdsCallbacks.Rewarded.OnAdRevenuePaid += OnRewardedRevenuePaid;
// 加载激励广告
CloudXSdk.LoadRewarded(RewardedAdUnitId);
}
public void ShowRewardedAd()
{
if (CloudXSdk.IsRewardedReady(RewardedAdUnitId))
{
// 显示时可附带广告位和自定义数据
CloudXSdk.ShowRewarded(RewardedAdUnitId, "bonus_coins", "custom_data");
}
else
{
Debug.LogWarning("激励广告尚未准备好");
}
}
private void OnRewardedLoaded(CloudXAd ad)
{
Debug.Log($"激励广告已加载: {ad.AdUnitId}");
}
private void OnRewardedLoadFailed(string adUnitId, CloudXError error)
{
Debug.LogError($"激励广告加载失败: {adUnitId} - {error}");
}
private void OnRewardedShown(CloudXAd ad)
{
Debug.Log($"激励广告已展示: {ad.AdUnitId}");
}
private void OnRewardedShowFailed(CloudXAd ad, CloudXError error)
{
Debug.LogError($"激励广告展示失败: {ad.AdUnitId} - {error}");
// 为下次重新加载
CloudXSdk.LoadRewarded(RewardedAdUnitId);
}
private void OnRewardedHidden(CloudXAd ad)
{
Debug.Log($"激励广告已隐藏: {ad.AdUnitId}");
// 为下次重新加载
CloudXSdk.LoadRewarded(RewardedAdUnitId);
}
private void OnRewardedClicked(CloudXAd ad)
{
Debug.Log($"激励广告被点击: {ad.AdUnitId}");
}
private void OnUserRewarded(CloudXAd ad, CloudXReward reward)
{
Debug.Log($"用户获得奖励: {reward.Amount} {reward.Label}");
// 在此处给用户奖励
GrantRewardToUser();
}
private void OnRewardedRevenuePaid(CloudXAd ad)
{
Debug.Log($"激励广告收入: ${ad.Revenue},来自 {ad.NetworkName}");
}
private void GrantRewardToUser()
{
// 您的奖励逻辑在此
Debug.Log("正在给用户奖励!");
}
}
高级功能
隐私控制
如果您的应用没有使用 CMP,可以在初始化之前手动覆盖隐私状态。
// 在 Initialize() 之前可选地设置手动隐私覆盖
CloudXSdk.SetHasUserConsent(true);
CloudXSdk.SetDoNotSell(false);
// 传入 null 可清除手动覆盖,重新交由 CMP 或 IAB 信号决定
CloudXSdk.SetHasUserConsent(null);
CloudXSdk.SetDoNotSell(null);
SetHasUserConsent(bool?) 用于设置 GDPR 同意覆盖。
SetDoNotSell(bool?) 用于设置 CCPA do-not-sell 覆盖。
- 如果存在 IAB 同意或隐私信号,它们会优先于这些手动覆盖值。
iOS ATT 使用说明文案
从 Unity SDK 2.2.4 开始,如果您的应用尚未在 Info.plist 中定义 NSUserTrackingUsageDescription,CloudX 的 iOS 后处理步骤会自动添加该字段。
- 默认值:
This uses device info for more personalized ads and content
- 如果您已经提供了
NSUserTrackingUsageDescription,CloudX 会保留您现有的值不变。
- 如果您希望展示自定义的 ATT 提示文案,请在
Info.plist 中显式设置自己的值。
用户定向
配置用户和应用属性以获得更好的广告定向。在 Initialize 之前调用这些方法。
// 设置哈希用户 ID
CloudXSdk.SetHashedUserId("hashed-user-id-12345");
// 设置用户级键值对
CloudXSdk.SetUserKeyValue("user_level", "premium");
CloudXSdk.SetUserKeyValue("age_group", "25-34");
// 设置应用级键值对
CloudXSdk.SetAppKeyValue("app_version", "1.0.0");
CloudXSdk.SetAppKeyValue("build_number", "123");
// 清除所有自定义键值对
CloudXSdk.ClearAllKeyValues();
收入追踪
所有广告格式都通过 OnAdRevenuePaid 事件提供收入回调。CloudXAd 对象包含收入信息:
CloudXAdsCallbacks.Banner.OnAdRevenuePaid += (ad) =>
{
Debug.Log($"收入: ${ad.Revenue:F4}");
Debug.Log($"广告网络: {ad.NetworkName}");
Debug.Log($"广告单元: {ad.AdUnitId}");
Debug.Log($"广告格式: {ad.AdFormat}");
Debug.Log($"广告位: {ad.Placement}");
Debug.Log($"网络广告位: {ad.NetworkPlacement}");
// 在您的分析中追踪收入
TrackRevenue(ad.Revenue, ad.NetworkName);
};