Unity接入TopOn
注意:该文档以Unity2019为例。
1.下载SDK
进入官方文档:集成说明 - TopOn Document (toponad.com)
如上图来到3.1 。 点击SDK打包系统
目前集成国外版, 选择否。如上图
选择需要的广告平台。如上图
点击Integrate , 点击下载。
解压文件,获得这几个包。可以看到各个广告的适配包和topon核心包AnyThinkCore。
2.Unity集成TopOn
(1)将SDK导入Unity
将这几个包一个个拖入项目Assets文件夹下。如上图
托如核心包会出现上图页面。 点击Add Selected Registries
点击 Apply。
最终结果图。
(2)集成
注意:设置当前平台为android,如上图。
勾选后可看到下图两个文件。
launcherTemplate.gradle需增加以下配置:
android {
......
defaultConfig {
applicationId '**APPLICATIONID**'
......
versionCode **VERSIONCODE**
versionName '**VERSIONNAME**'
multiDexEnabled true //添加此配置,是为了当代码行数超过64k的时候设置的
}
......
}
添加以下代码到如上图两个文件中
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
**BUILD_SCRIPT_DEPS**}
}
launcherTemplate 如上图 mainTemplate同理。
打开Preferences
设置Gradle版本。如图。 如果没有gradle-6.7.1 自行百度下载。
设置SDK版本如下图。
按照下图,生成LauncherManifest.xml文件。
注意:复制以下代码到生成后的LauncherManifest.xml。
<?xml version="1.0" encoding="utf-8"?>
<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="preferExternal">
<!--必须要有的权限-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
<application android:label="@string/app_name"
android:icon="@mipmap/app_icon"
tools:replace="android:networkSecurityConfig"
android:networkSecurityConfig="@xml/network_security_config_unity">
<!--这个设置主要是为了适配9.0以上的机器(必须使用)-->
<uses-library android:name="org.apache.http.legacy" android:required="false" />
</application>
</manifest>
在Assets/Plugins/Android/res/xml目录下创建network_security_config_unity.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>v5.7.2之前的版本可跳过此步骤。从v5.7.2开始,如果有聚合了Admob,则必须在LauncherManifest.xml中额外添加以下配置(value值需配置Admob后台创建的应用的ID):
<manifest>
<application>
<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
</application>
</manifest>
按照下图,生成gradleTemplate.properties文件。
注意:针对生成后的gradleTemplate.properties需增加以下配置:
org.gradle.jvmargs=-XmxJVM_HEAP_SIZEM
org.gradle.parallel=trueADDITIONAL_PROPERTIES
//添加以下配置
android.enableJetifier=true
android.useAndroidX=true
依赖解析
从v5.6.5版本开始调整了广告平台SDK的依赖引入方式,请根据以下步骤进行操作:
确保已经生成mainTemplate.gradle文件
勾选 Patch mainTemplate.gradle 选项(Unity 菜单栏:Assets → External Dependency Manager → Android Resolver → Settings)
开始解析依赖(Unity 菜单栏:Assets → External Dependency Manager → Android Resolver → Resolve),解析成功后将在mainTemplate.gradle文件中引入依赖。如果解析后没有任何反应,请尝试点击 “Force Resolve” 进行重试
3.调用广告
新建MainScenes脚本,该脚本用来初始化topon广告。代码如下:
其中APPKEY 和 APPKID 需要改成自己广告的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using AnyThinkAds.Api;
using UnityEngine.UI;
using System;
/// <summary>
/// 初始化TopOn
/// </summary>
public class MainScenes : MonoBehaviour {
private string APPKEY = "对应KEY";
private string APPKID = "对应ID";
//private interstitialScenes intersScene;
[NonSerialized]
public vidoeScenes vidSce;
[NonSerialized]
public interstitialScenes intSce;
[NonSerialized]
public bannerScenes banSce;
public static MainScenes instance;
void Awake () {
if (instance == null)
instance = this;
else
Destroy(transform.gameObject);
initSDK();
DontDestroyOnLoad(this);
vidSce = GetComponent<vidoeScenes>();
intSce = GetComponent<interstitialScenes>();
banSce = GetComponent<bannerScenes>();
}
void Update () {
}
private class InitListener : ATSDKInitListener
{
public void initSuccess()
{
Debug.Log("Developer Develop callback SDK initSuccess");
}
public void initFail(string msg)
{
Debug.Log("Developer callback SDK initFail:" + msg);
}
}
private class GetLocationListener:ATGetUserLocationListener
{
public void didGetUserLocation(int location)
{
//Debug.Log("Developer callback didGetUserLocation(): " + location);
if(location == ATSDKAPI.kATUserLocationInEU && ATSDKAPI.getGDPRLevel() == ATSDKAPI.UNKNOWN)
{
ATSDKAPI.showGDPRAuth();
}
}
}
public void initSDK(){
/*Debug.Log ("*********init sdk");
Debug.Log("Developer Version of the runtime: " + Application.unityVersion);
Debug.Log ("Developer init sdk");
Debug.Log(" Developer Screen size : {" + Screen.width + ", " + Screen.height + "}");
*/
//ATSDKAPI.setChannel("unity3d_test_channel");
//ATSDKAPI.setSubChannel("unity3d_test_Subchannel");
//ATSDKAPI.initCustomMap(new Dictionary<string, string> { { "channel", "huawei" } });
//ATSDKAPI.setCustomDataForPlacementID(new Dictionary<string, string> { { "unity3d_data_pl", "test_data_pl" } },"b5b728e7a08cd4");
/**/ATSDKAPI.setLogDebug(true);
//Debug.Log("Developer DataConsent: " + ATSDKAPI.getGDPRLevel());
//Debug.Log("Developer isEUTrafic: " + ATSDKAPI.isEUTraffic());
ATSDKAPI.getUserLocation(new GetLocationListener());
#if UNITY_ANDROID
ATSDKAPI.initSDK(APPKID, APPKEY, new InitListener());
#endif
}
}
新建bannerScenes脚本,该脚本用来加载banner 和 展现banner广告。
其中mPlacementId_banner_all需要更换成对应id
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using AnyThinkAds.Api;
using UnityEngine.UI;
using AnyThinkAds.ThirdParty.MiniJSON;
using System;
public class bannerScenes : MonoBehaviour {
#if UNITY_ANDROID
static string mPlacementId_banner_all = "更换对应id";
static string showingScenario = "f600e6039e152c";
#elif UNITY_IOS || UNITY_IPHONE
static string mPlacementId_banner_all = "b5bacaccb61c29";
//static string mPlacementId_banner_all = "b5bacaccb61c29";
static string showingScenario = "";
#endif
private int screenWidth;
// Use this for initialization
void Start () {
this.screenWidth = Screen.width;
loadBannerAd();
showBannerAd();
}
// Update is called once per frame
void Update () {
}
private void OnDestroy()
{
}
static BannerCallback bannerCallback ;
public void loadBannerAd() {
if(bannerCallback == null){
bannerCallback = new BannerCallback();
ATBannerAd.Instance.setListener(bannerCallback);
}
Dictionary<string, object> jsonmap = new Dictionary<string,object>();
#if UNITY_ANDROID
ATSize bannerSize = new ATSize(screenWidth, 50* screenWidth/350, true);
jsonmap.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSizeStruct, bannerSize);
jsonmap.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraAdaptiveWidth, bannerSize.width);
jsonmap.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraAdaptiveOrientation, ATBannerAdLoadingExtra.kATBannerAdLoadingExtraAdaptiveOrientationPortrait);
#elif UNITY_IOS || UNITY_IPHONE
ATSize bannerSize = new ATSize(320, 50, false);
jsonmap.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSizeStruct, bannerSize);
jsonmap.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraAdaptiveWidth, bannerSize.width);
jsonmap.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraAdaptiveOrientation, ATBannerAdLoadingExtra.kATBannerAdLoadingExtraAdaptiveOrientationPortrait);
#endif
ATBannerAd.Instance.loadBannerAd(mPlacementId_banner_all, jsonmap);
}
public void showBannerAd() {
//string adStatus = ATBannerAd.Instance.checkAdStatus(mPlacementId_banner_all);
//Debug.Log("*************Developer checkAdStatus banner...." + adStatus);
//Debug.Log("*************Developer show banner *************");
// ATRect arpuRect = new ATRect(0,50, this.screenWidth, 300, true);
// ATBannerAd.Instance.showBannerAd(mPlacementId_banner_all, arpuRect);
// ATBannerAd.Instance.showBannerAd(mPlacementId_banner_all, ATBannerAdLoadingExtra.kATBannerAdShowingPisitionBottom);
ATBannerAd.Instance.showBannerAd(mPlacementId_banner_all, ATBannerAdLoadingExtra.kATBannerAdShowingPisitionBottom);
// Dictionary<string, string> jsonmap = new Dictionary<string, string>();
// jsonmap.Add(AnyThinkAds.Api.ATConst.SCENARIO, showingScenario);
// //ATBannerAd.Instance.showBannerAd(mPlacementId_banner_all, arpuRect, jsonmap);
// ATBannerAd.Instance.showBannerAd(mPlacementId_banner_all, ATBannerAdLoadingExtra.kATBannerAdShowingPisitionTop, jsonmap);
}
public void removeBannerAd() {
ATBannerAd.Instance.cleanBannerAd(mPlacementId_banner_all);
}
public void hideBannerAd() {
ATBannerAd.Instance.hideBannerAd(mPlacementId_banner_all);
}
/*
Use this method when you want to reshow a banner that is previously hidden(by calling hideBannerAd)
*/
public void reshowBannerAd() {
ATBannerAd.Instance.showBannerAd(mPlacementId_banner_all);
}
class BannerCallback : ATBannerAdListener
{
public void onAdAutoRefresh(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onAdAutoRefresh :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onAdAutoRefreshFail(string placementId, string code, string message)
{
//Debug.Log("Developer callback onAdAutoRefreshFail : "+ placementId + "--code:" + code + "--msg:" + message);
}
public void onAdClick(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onAdClick :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onAdClose(string placementId)
{
//Debug.Log("Developer callback onAdClose :" + placementId);
}
public void onAdCloseButtonTapped(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onAdCloseButtonTapped :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onAdImpress(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onAdImpress :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onAdLoad(string placementId)
{
//Debug.Log("Developer callback onAdLoad :" + placementId);
}
public void onAdLoadFail(string placementId, string code, string message)
{
//Debug.Log("************Developer callback onAdLoadFail : : " + placementId + "--code:" + code + "--msg:" + message);
}
}
}
新建interstitialScenes脚本 , 该脚本用来加载插屏,并提供调用接口
其中mPlacementId_interstitial_all要跟换成对应id
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using AnyThinkAds.Api;
using UnityEngine.UI;
using AnyThinkAds.ThirdParty.MiniJSON;
using UnityEngine.EventSystems;
using System;
public class interstitialScenes : MonoBehaviour {
#if UNITY_ANDROID
//static string mPlacementId_interstitial_all = "b5bbdc8e9ef916";
static string mPlacementId_interstitial_all = "更换对应id";
static string showingScenario = "f5e71c49060ab3";
#elif UNITY_IOS || UNITY_IPHONE
static string mPlacementId_interstitial_all = "b5bacad26a752a";
static string showingScenario = "f5e549727efc49";
#endif
// Use this for initialization
void Start () {
loadInterstitialAd();
//EventManager.ShowInterstitialAd.BoradCastEvent();
}
// Update is called once per frame
void Update () {
}
static InterstitalCallback callback;
public void loadInterstitialAd() {
if(callback == null) {
callback = new InterstitalCallback();
ATInterstitialAd.Instance.setListener(callback);
}
//Debug.Log("**********loadInterstitialAd");
Dictionary<string,string> jsonmap = new Dictionary<string,string>();
jsonmap.Add(AnyThinkAds.Api.ATConst.USE_REWARDED_VIDEO_AS_INTERSTITIAL, AnyThinkAds.Api.ATConst.USE_REWARDED_VIDEO_AS_INTERSTITIAL_NO);
//jsonmap.Add(AnyThinkAds.Api.ATConst.USE_REWARDED_VIDEO_AS_INTERSTITIAL, AnyThinkAds.Api.ATConst.USE_REWARDED_VIDEO_AS_INTERSTITIAL_YES);
ATInterstitialAd.Instance.loadInterstitialAd(mPlacementId_interstitial_all, jsonmap);
}
public void isReady()
{
bool b = ATInterstitialAd.Instance.hasInterstitialAdReady(mPlacementId_interstitial_all);
//Debug.Log("Developer isReady interstitial...." + b);
string adStatus = ATInterstitialAd.Instance.checkAdStatus(mPlacementId_interstitial_all);
//Debug.Log("Developer checkAdStatus interstitial...." + adStatus);
}
public void showInterstitialAd()
{
Dictionary<string, string> jsonmap = new Dictionary<string, string>();
jsonmap.Add(AnyThinkAds.Api.ATConst.SCENARIO, showingScenario);
ATInterstitialAd.Instance.showInterstitialAd(mPlacementId_interstitial_all, jsonmap);
}
private void OnDestroy()
{
}
class InterstitalCallback : ATInterstitialAdListener
{
public void onInterstitialAdClick(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onInterstitialAdClick :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onInterstitialAdClose(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onInterstitialAdClose :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onInterstitialAdEndPlayingVideo(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onInterstitialAdEndPlayingVideo :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onInterstitialAdFailedToPlayVideo(string placementId, string code, string message)
{
//Debug.Log("Developer callback onInterstitialAdFailedToPlayVideo :" + placementId + "--code:" + code + "--msg:" + message);
}
public void onInterstitialAdLoad(string placementId)
{
//Debug.Log("Developer callback onInterstitialAdLoad :" + placementId);
}
public void onInterstitialAdLoadFail(string placementId, string code, string message)
{
//Debug.Log("*****Developer callback onInterstitialAdLoadFail :" + placementId + "--code:" + code + "--msg:" + message);
//loadInterstitiaAd();
}
public void onInterstitialAdShow(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onInterstitialAdShow :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onInterstitialAdStartPlayingVideo(string placementId, ATCallbackInfo callbackInfo)
{
//Debug.Log("Developer callback onInterstitialAdStartPlayingVideo :" + placementId + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onInterstitialAdFailedToShow(string placementId)
{
//Debug.Log("Developer callback onInterstitialAdFailedToShow :" + placementId);
}
}
}
新建vidoeScenes脚本,该脚本用来加载激励视频,并提供调用接口
其中mPlacementId_rewardvideo_all更换成对应id
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using AnyThinkAds.Api;
using UnityEngine.UI;
using AnyThinkAds.ThirdParty.MiniJSON;
using System;
public class vidoeScenes : MonoBehaviour {
#if UNITY_ANDROID
//static string mPlacementId_rewardvideo_all = "b5b449f75948c5";
static string mPlacementId_rewardvideo_all = "更换对应id";
static string showingScenario = "f5e71c46d1a28f";
#elif UNITY_IOS || UNITY_IPHONE
static string mPlacementId_rewardvideo_all = "b5b44a0f115321";//"b5b44a0f115321";
static string showingScenario = "f5e54970dc84e6";
#endif
ATRewardedVideo rewardedVideo;
// Use this for initialization
void Start () {
loadVideo();
}
// Update is called once per frame
void Update () {
}
static ATCallbackListener callbackListener;
public void loadVideo(){
if(callbackListener == null){
callbackListener = new ATCallbackListener();
//Debug.Log("Developer init video....placementId:" + mPlacementId_rewardvideo_all);
ATRewardedVideo.Instance.setListener(callbackListener);
}
//Debug.Log("**********loadVideo");
ATSDKAPI.setCustomDataForPlacementID(new Dictionary<string, string> { { "placement_custom_key", "placement_custom" } }, mPlacementId_rewardvideo_all);
Dictionary<string,string> jsonmap = new Dictionary<string,string>();
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);
}
public void showVideo(){
bool b = ATRewardedVideo.Instance.hasAdReady(mPlacementId_rewardvideo_all);
if (!b)
{
//Debug.Log("******没有广告缓存重新 loadVideo");
//loadVideo();
}
//Debug.Log (" ********************Developer show video.... ********************");
Dictionary<string, string> jsonmap = new Dictionary<string, string>();
jsonmap.Add(AnyThinkAds.Api.ATConst.SCENARIO, showingScenario);
ATRewardedVideo.Instance.showAd(mPlacementId_rewardvideo_all, jsonmap);
}
private void OnDestroy()
{
}
public void isReady(){
// Debug.Log ("Developer isReady ?....");
bool b = ATRewardedVideo.Instance.hasAdReady(mPlacementId_rewardvideo_all);
//Debug.Log("Developer isReady video...." + b);
string adStatus = ATRewardedVideo.Instance.checkAdStatus(mPlacementId_rewardvideo_all);
//Debug.Log("Developer checkAdStatus video...." + adStatus);
}
class ATCallbackListener : ATRewardedVideoListener {
public void onRewardedVideoAdLoaded(string placementId)
{
//Debug.Log("Developer onRewardedVideoAdLoaded------");
}
public void onRewardedVideoAdLoadFail(string placementId, string code, string message){
//Debug.Log("***************Developer onRewardedVideoAdLoadFail------:code" + code + "--message:" + message);
}
public void onRewardedVideoAdPlayStart(string placementId, ATCallbackInfo callbackInfo){
//Debug.Log("Developer onRewardedVideoAdPlayStart------" + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onRewardedVideoAdPlayEnd(string placementId, ATCallbackInfo callbackInfo){
//Debug.Log("Developer onRewardedVideoAdPlayEnd------" + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onRewardedVideoAdPlayFail(string placementId, string code, string message){
//Debug.Log("Developer onRewardedVideoAdPlayFail------code:" + code + "---message:" + message);
}
public void onRewardedVideoAdPlayClosed(string placementId, bool isReward, ATCallbackInfo callbackInfo){
//Debug.Log("Developer onRewardedVideoAdPlayClosed------isReward:" + isReward + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onRewardedVideoAdPlayClicked(string placementId, ATCallbackInfo callbackInfo){
//Debug.Log("Developer onRewardVideoAdPlayClicked------" + "->" + Json.Serialize(callbackInfo.toDictionary()));
}
public void onReward(string placementId, ATCallbackInfo callbackInfo){
}
}
}
创建空物体,取名AD将,将以上脚本添加到物体。
大功告成。 现在可以在任何地方通过以下代码调用广告。
调用banner
MainScenes.instance.banSce.showBannerAd();
调用插屏
MainScenes.instance.intSce.showInterstitialAd();
调用激励视频
MainScenes.instance.vidSce.showVideo();
4.测试集成
测试集成需要打开Debug模式,MainScenes脚本中已经打开,如下图。
直接打包apk,安装到手机 -> 手机打开开发者模式 -> 用数据线连接电脑。 ->
打开AndroidStudio 的 Logcat -> 运行应用, 查看日志, 日志如下图。