写在前面
本文基于已经在TapTap平台上架应用成功,利用Topon聚合平台接入穿山甲广告SDK的流程,我们先把Topon平台的账号注册好才能开始后续操作,后续上架国内其他平台,理论上只要包名(Package Name)和SHA1值不变,广告就可以复用。
Topon注册页面:https://www.toponad.com/zh-cn
Topon功能文档指南:https://newdocs.toponad.com/docs/pqxB1u
一、创建应用和广告
申请完账号之后,根据功能文档的指引创建对应平台的应用以及需要投放的广告类型,这个账号只是官方子账号的中转媒介,后面还会根据你注册的账号里的应用广告等信息再创建一个子账号,这个子账号里的参数才是真实有效的,因为个人身份是无法对接穿山甲的,灰色地带,不便多说。
下面简单介绍一下个人账号应用广告等创建的流程:
1.创建应用
2.创建广告位
3.以下观点为个人猜想,胡说八道,毫无逻辑可言,请无视。
创建成功之后,跟客服沟通,客服会让你提供一个新的邮箱创建一个子账号。我这里大胆猜测下,其实要创建的账号一共有3个,第1个是你一开始Topon注册的时候创建的,第2个账号就是官方根据你第1个账号里的应用包名,广告位类型所提取出来的子账号,子账号里有聚合好的广告平台和应用的真实ID、密钥,广告位的真实ID,第3个账号应该是一个母账号,母账号用来管理你聚合的平台,子账号给你看广告创造的实际收益,另外我们没有软著的话,只能接穿山甲和百度的广告。
二、下载ToponSDK
子账号创建完成之后,可以在应用界面看到一些重要参数,如应用ID,App Key(编辑界面),广告位ID,包名等等,后续就是通过应用ID、App Key、广告位ID来确定给你的哪个应用投放哪种具体的广告类型。
这里下载SDK的方式有两种:
第一种是在Web端集成好你要聚合的平台,然后在生成SDK插件,适用于Android Studio原生接入。
第二种是下载Unity的广告SDK插件,然后再Unity自主选择聚合的平台,这里我们使用的就是第二种方式,插件导入成功之后,打开AnyThink面板,选择你要聚合的广告平台,这里我们以穿山甲为例,在Csj栏点击Install即可。
Unity插件TopOn SDK下载地址:https://app.toponad.com/m/sdk/download
Topon Unity插件导入说明:https://newdocs.toponad.com/docs/hd01b0
插件使用说明
-
Region (地区):插件提供两个地区选择:中国地区(ChinaMainland)和海外地区(Overseas),仅用于Android下载相应地区的network,iOS支持全球发布,使用任何一个地区都可以。
-
AndroidX:是用于开发 Android 应用程序的支持库集合,仅适用于 Android 平台。在选择中国地区时,会提供一个选项来确定是否使用 AndroidX。值得注意的是,在海外地区,默认需要使用AndroidX。
-
Upgrade :如果其中一个版本号(Unity 3D 插件、Android、iOS)落后于最新版本,则显示为可点击状态。点击后,如果是 Android 或 iOS 需要更新,则会自动下载并更新 core 包。如果 Unity 3D 插件版本需要更新,则跳转到插件下载页面,需要手动下载最新插件并重新导入插件。
-
Upgrade All:如果当前已安装的network列表中有需要更新的network,显示为可点击状态。点击后,会一次性更新所有需要更新的network。
-
Install:点击安装network。
-
删除按钮:删除已安装的network。
注意事项
-
如果你切换地区,Android和iOS已安装的network列表将被清除,请在切换前确认所需地区,以免需要重新安装network。
-
从插件版本2.0.1开始,国内穿山甲使用Csj名称,海外穿山甲使用Pangle名称。
插件导入
按照以下步骤导入插件:
-
打开Unity,依次选择 Assets > Import Package > Custom Package 。
-
选择您下载的 Unity 插件文件。
-
在 Import Unity Package 对话框中,单击 Import。
-
插件导入后,查看Unity菜单栏的选项,点击 AnyThink 打开插件。
注意: 如果有导入旧的插件,需要先删除旧的插件,直接删除 Assets 目录下的 AnyThinkPlugin 目录即可。
集成环境
-
Unity 2019.x.x 或更高版本。
在 Project Settings -> Player -> Android Tab -> Publish Settings -> Build,勾选Custom Main Gradle Template 和Custom Gradle Properties Tamplate。
注意事项
Android缓存处理
构建 Android 之前,避免受缓存影响导致某些network没集成进去,建议按照以下步骤点击 Force Resolve:
菜单栏Assets > External Dependency Manager > Android Resolver > Force Resolve.
三、对接对应类型广告
相信大家都不是第一次在Unity中接入广告SDK了,我们首先做的第一部就是要根据我们的应用ID、AppKey、广告位ID等参数来初始化广告。
//(可选配置)设置自定义的Map信息,可匹配后台配置的广告商顺序的列表(App纬度)
//注意:调用此方法会清除setChannel()、setSubChannel()方法设置的信息,如果有设置这些信息,请在调用此方法后重新设置
ATSDKAPI.initCustomMap(new Dictionary<string, string> { { "unity3d_data", "test_data" } });
//(可选配置)设置自定义的Map信息,可匹配后台配置的广告商顺序的列表(Placement纬度)
ATSDKAPI.setCustomDataForPlacementID(new Dictionary<string, string> { { "unity3d_data_pl", "test_data_pl" } } ,placementId);
//(可选配置)设置渠道的信息,开发者可以通过该渠道信息在后台来区分看各个渠道的广告数据
//注意:如果有使用initCustomMap()方法,必须在initCustomMap()方法之后调用此方法
ATSDKAPI.setChannel("unity3d_test_channel");
//(可选配置)设置子渠道的信息,开发者可以通过该渠道信息在后台来区分看各个渠道的子渠道广告数据
//注意:如果有使用initCustomMap()方法,必须在initCustomMap()方法之后调用此方法
ATSDKAPI.setSubChannel("unity3d_test_subchannel");
//设置开启Debug日志(强烈建议测试阶段开启,方便排查问题)
ATSDKAPI.setLogDebug(true);
//(必须配置)SDK的初始化
ATSDKAPI.initSDK("a5c4ad280995c9", "7b4e37f819dbee652ef79c4506e14288");//Use your own app_id & app_key here
ATSDKAPI.initSDK里的两个参数就是你的应用ID和AppKey。
激励视频广告集成说明:https://newdocs.toponad.com/docs/ZjSzvu
这里我们以eCPM最高的激励视频广告为例,演示接入流程。
-
加载激励视频
使用以下代码加载激励视频广告:
public void loadVideo()
{
ATRewardedVideo.Instance.client.onAdLoadEvent += onAdLoad;
ATRewardedVideo.Instance.client.onAdLoadFailureEvent += onAdLoadFail;
ATRewardedVideo.Instance.client.onAdVideoStartEvent += onAdVideoStartEvent;
ATRewardedVideo.Instance.client.onAdVideoEndEvent += onAdVideoEndEvent;
ATRewardedVideo.Instance.client.onAdVideoFailureEvent += onAdVideoPlayFail;
ATRewardedVideo.Instance.client.onAdClickEvent += onAdClick;
ATRewardedVideo.Instance.client.onRewardEvent += onReward;
ATRewardedVideo.Instance.client.onAdVideoCloseEvent += onAdVideoClosedEvent;
Dictionary<string,string> jsonmap = new Dictionary<string,string>();
//如果需要通过开发者的服务器进行奖励的下发(部分广告平台支持此服务器激励),则需要传递下面两个key
//ATConst.USERID_KEY必传,用于标识每个用户;ATConst.USER_EXTRA_DATA为可选参数,传入后将透传到开发者的服务器
jsonmap.Add(ATConst.USERID_KEY, "test_user_id");
jsonmap.Add(ATConst.USER_EXTRA_DATA, "test_user_extra_data");
ATRewardedVideo.Instance.loadVideoAd(mPlacementId_rewardvideo_all,jsonmap);
}
-
判断是否有广告缓存
ATRewardedVideo.Instance.hasAdReady(mPlacementId_rewardvideo_all);
-
展示激励视频
mPlacementId_rewardvideo_all为广告位ID
,只要调用展示api并传递展示广告位ID作为参数:
public void showVideo()
{
Debug.Log ("Developer show video....");
ATRewardedVideo.Instance.showAd(mPlacementId_rewardvideo_all);
}
-
对应回调方法介绍:
/广告加载成功
ATRewardedVideo.Instance.client.onAdLoadEvent += onAdLoad;
//广告加载失败
ATRewardedVideo.Instance.client.onAdLoadFailureEvent += onAdLoadFail;
//广告展示的回调(可依赖这个回调统计展示数据)
ATRewardedVideo.Instance.client.onAdVideoStartEvent += onAdVideoStartEvent;
//广告播放结束
ATRewardedVideo.Instance.client.onAdVideoEndEvent += onAdVideoEndEvent;
//广告视频播放失败
ATRewardedVideo.Instance.client.onAdVideoFailureEvent += onAdVideoPlayFail;
//广告点击
ATRewardedVideo.Instance.client.onAdClickEvent += onAdClick;
//广告激励回调(可依赖该监听下发游戏激励)
ATRewardedVideo.Instance.client.onRewardEvent += onReward;
//广告被关闭
ATRewardedVideo.Instance.client.onAdVideoCloseEvent += onAdVideoClosedEvent;
//广告加载成功
public void onAdLoad(object sender,ATAdEventArgs erg)
{
Debug.Log("Developer callback onAdLoad :" + erg.placementId);
}
//广告加载失败
public void onAdLoadFail(object sender,ATAdErrorEventArgs erg )
{
Debug.Log("Developer callback onAdLoadFail :" + erg.placementId + "--erg.code:" + code + "--msg:" + erg.message);
}
public void onAdVideoStartEvent(object sender, ATAdEventArgs erg) {
Debug.Log("Developer onAdVideoStartEvent------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
}
public void onAdVideoEndEvent(object sender, ATAdEventArgs erg)
{
Debug.Log("Developer onAdVideoEndEvent------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
}
public void onAdVideoPlayFail(object sender, ATAdErrorEventArgs erg)
{
Debug.Log("Developer onAdVideoClosedEvent------" + "->" + JsonMapper.ToJson(erg.errorMessage));
}
//sender 为广告类型对象,erg为返回信息
//广告被点击
public void onAdClick(object sender,ATAdEventArgs erg)
{
Debug.Log("Developer callback onAdClick :" + erg.placementId);
}
public void onReward(object sender, ATAdEventArgs erg)
{
Debug.Log("Developer onReward------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
}
public void onAdVideoClosedEvent(object sender, ATAdEventArgs erg)
{
Debug.Log("Developer onAdVideoClosedEvent------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
}
public void startLoadingADSource(object sender,ATAdEventArgs erg){
Debug.Log("Developer startLoadingADSource------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toAdsourceDictionary()));
}
public void finishLoadingADSource(object sender,ATAdEventArgs erg){
Debug.Log("Developer finishLoadingADSource------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toAdsourceDictionary()));
}
public void failToLoadADSource(object sender,ATAdErrorEventArgs erg ){
Debug.Log("Developer failToLoadADSource------erg.errorCode:" + erg.errorCode + "---erg.errorMessage:" + erg.errorMessage+ "->" + JsonMapper.ToJson(erg.callbackInfo.toAdsourceDictionary()));
}
public void startBiddingADSource(object sender,ATAdEventArgs erg){
Debug.Log("Developer startBiddingADSource------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toAdsourceDictionary()));
}
public void finishBiddingADSource(object sender,ATAdEventArgs erg){
Debug.Log("Developer finishBiddingADSource------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toAdsourceDictionary()));
}
public void failBiddingADSource(object sender,ATAdErrorEventArgs erg ){
Debug.Log("Developer failBiddingADSource------erg.errorCode:" + erg.errorCode + "---erg.errorMessage:" + erg.errorMessage+ "->" + JsonMapper.ToJson(erg.callbackInfo.toAdsourceDictionary()));
}
这里我讲一下我个人的广告接入逻辑,无论接入任何类型的广告,都要在加载广告之前对广告进行初始化,确保初始化完成之后再加载广告,这样用户触发播放广告的时候就可以直接播放了,播放广告之后,在广告提前关闭和观看一定时间获得奖励的回调方法中再次加载广告,这样下次就可以直接播放广告了。
加载广告
播放广告
获得奖励回调
提前关闭广告回调
四、打包真机测试
广告接入完成,逻辑形成闭环之后,一定要在实机测试,确认广告在实机可以正常加载,回调奖励无误之后,务必跟Topon客服人员沟通,让他们把广告转正,不然没有任何收益。