Unity接入穿山甲广告(使用unity插件)

自己做的小游戏需要接广告,之前尝试过UnityAds和AdMob,但是都有点小问题。UnityAds对国内本土支持不好,Banner广告经常没有内容(VPN切换成美国,就有了)。Admob基本上都要对接到googlePlay,国内没办法。然后找了国内的广告SDK。

研究了好久,网上的教程都比较老,而且我在AndroidStudio方面完全是小白(本篇教程写于2020年9月,使用的SDK版本为V3.0)。

准备工作

  1. 创建账号https://www.pangle.cn/
  2. 添加应用
  3. 添加代码位(广告位)
  4. 下载SDK(接入中心-穿山甲SDK Unity插件)


    image.png

为什么选Unity插件不用原生?很简单,我不会安卓和IOS开发

Unity部分工作

  • 打开Unity(我用的是2019.4.10,不同版本的导出的AndroidStudio工程不太一样,后面会说)
  • 导入插件


    image.png

两个都导进来

  • 双击打开Example/Example场景,发布工程,不能直接打包成APK,会报错,要导出为AndroidStudio工程。
  • 2019版本导出方法:


    image.png

勾选Export Project,然后点Export就好了

  • 2018导出方法:BuildSystem选为Gradle,勾选Export Project,然后点Export就好了

ProjectSetting相应的打包设置不会的请百度

AndroidStudio部分工作

  • 用AndroidStudio打开导出的项目


    image.png

弹出这个选择OK就行,然后等syncing(可能会比较慢)

  • 切换为Project模式,现在就是项目的目录了


    image.png
  • 点开unityLibrary-src-main-java,右键java-New-Package,name输入com.bytedance.android


    image.png

完成之后的结构

  • 打开导入到unity中的案例文件夹


    image.png

    把红框里的这些脚本复制到刚才新建的Package下面


    image.png

完成之后的结构

  • 然后就可以直接打包测试案例场景了。在AndroidStudio顶部工具栏Build-Build Bundle(s)/APK(s)-Build APK(s),等待显示打包成功。(打出来的apk在当前AndroidStudio项目目录的launcher-build-outputs-apk-debug里,直接放到手机上安装测试)

如果是Unity2018或以下版本导出的项目

  • 新建的Package位置在这里:


    image.png

    其余的步骤相同

设置成自己的项目

  • 打开UnionApplication.java,把appId和appName改为自己在网站上创建的项目


    image.png
  • 在Load广告的cs代码,把CodeId改为自己添加的代码位ID


    image.png

调用广告

  • 先Load,再Show,具体的调用方法在Example.cs脚本中都有,直接copy就行
  • 具体的Api说明看文档


    image.png

IOS

  • 修改Example中的UnionAppController.mm的配置


    image.png
  • 直接编译xcode,运行下看看有没有问题,如果有问题,把UnionAppController.mm放到unity的Plugins/IOS目录下重新编译

修改Banner广告位置

Android

  • 在unity中找到java脚本:NativeAdManager.java
  • 找到脚本中showExpressBannerAd()方法,修改渲染成功的方法onRenderSuccess(),
layoutParams.gravity = Gravity.CENTER | Gravity.BOTTOM; //Banner位于应用底部中间
layoutParams.gravity = Gravity.CENTER | Gravity.TOP;//Banner位于应用顶部中间

记住,在Unity中修改,然后导出包,不要先导出包再在AndroidStudio中修改(原因我也不知道,反正这都是我试了之后的)

IOS

  • 在你自己写的展示Banner广告代码中设置广告的位置:
public void ShowExpressBannerAd()
{
#if UNITY_IOS
        if (iExpressBannerAd == null)
        {
            Debug.LogError("请先加载广告");
            return;
        }

        //坐标的基点是Banner广告的左上角顶点,所以(0,0)就是位于屏幕最顶端
        //如果load的时候设置的广告尺寸宽度与屏幕宽度不相等的话,就需要自己计算x坐标
        int x = 0;
        int y = Screen.height - (Screen.width / 640 * 100);

        // 如果Banner位于应用顶部,可以加一些宏,如果是有刘海的iphone,让 y=100,避免被刘海遮挡,我的banner是在屏幕底部,所以就不用了
        //if (y == 0)
        //{
        //    y = 100; // 防止Demo里刘海遮挡
        //}

        iExpressBannerAd.ShowExpressAd(x, y);
#else
        //安卓的显示代码
#endif
}

各种坑的解决方式

  1. 不要用NativeBannerAd,NativeIntersititialAd等等原生广告,官方已经不支持了,都用模板广告,也就是Example脚本中带Express的方法(ExpressBannerAd)
  2. 我以为java脚本放在unity工程中不会影响androidstudio项目,没想到打包出来对应的AndroidStudio脚本也会变,所以Example文件夹中的java脚本可以直接改成自己的appid,以防打包出来又变成测试的appid。(这个问题是unity2019版本,因为这个版本中,unity会自动把项目中的java脚本和xcode工程脚本编译,所以可以直接在unity中修改之后再编译)
  3. 接了SDK之后,打包出来的apk启动的瞬间会先显示一下android标题栏,这个需要修改下AndroidManifest文件,在application中添加android:theme="@style/UnityThemeSelector"


    image.png
  4. 一些没必要的权限能不加就不加
    下面是我的AndroidManifest.xml完整版
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.product">

    <!--必须要有的权限-->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <!--最好能提供的权限-->
    <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->

    <!-- 如果有视频相关的广告且使用textureView播放,请务必添加,否则黑屏 -->
    <!--<uses-permission android:name="android.permission.WAKE_LOCK" />-->
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>
    <application
        android:name="com.bytedance.android.UnionApplication"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:theme="@style/UnityThemeSelector"
        android:allowBackup="true"
        android:debuggable="true"
        android:supportsRtl="true">
        <uses-library android:name="org.apache.http.legacy" android:required="false"/>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
             android:label="@string/app_name"
             android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data android:name="android.app.lib_name" android:value="unity"/>
        <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false"/>
    </activity>
     <provider
            android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
            android:authorities="${applicationId}.TTFileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

        <provider
            android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
            android:authorities="${applicationId}.TTMultiProvider"
            android:exported="false" />
    </application>
</manifest>
  1. 苹果打包编译真机调试报错


    image.png

    可以看到是LoadExpressRewardAd()方法中出现的,只需要把AdSlot中所有需要的参数都填上内容即可

  2. 安卓设备,激励视频广告在播放的中途切换后台再切回来,广告直接消失了。
    解决方法:在导出的AndroidStudio项目中修改AndroidManifest.xml,找到activity的launchMode,默认是"singleTask",改成"singleTop"就可以了,只能在AndroidStudio中设置,Unity中改了也不生效,unity强制设置成了singleTask


    image.png
  1. 使用unity插件升级最近的android和ios SDK时,直接在官方下载最新的对应SDK,安卓把Plugins/Android/open_ad_sdk.aar替换成安卓SDK里的open_ad_sdk.aar,IOS把Plugins/IOS目录下的BUAdSDK.bundle,BUAdSDK.framework,BUFoundation.framework替换成IOS SDK里Frameworks里的。


    image.png

升级之后直接打包的话,原先的FullScreenVideoAD和RewardVideoAD会加载不了,需要在加载这两种广告的方法中,adSlot添加上.SetExpressViewAcceptedSize(400, 80)参数,只要参数不为0即可。


image.png
  1. ios设备banner广告位置不适配。我自己在iphoneSE和iphoneX上都是正常的,在屏幕最底部,但是放到iphone8plus上,位置就跑了。这个提交了穿山甲的工单咨询了下,说是因为unity自身的bug,导致获取的屏幕尺寸不对,需要在xcode工程中修改脚本,解决方法:
    在xcode工程中,找到ExpressBannerAd.mm,找到方法UnionPlatform_ExpressBannersAd_Load,然后再设置banner的尺寸,然后在UnionPlatform_ExpressBannersAd_Show方法中,重新设置banner的位置。
    看我加注释的几行就行。
    void UnionPlatform_ExpressBannersAd_Load(
                                      const char* slotID,
                                      float width,
                                      float height,
                                      BOOL isSupportDeepLink,
                                      ExpressAd_OnLoad onLoad,
                                      ExpressAd_OnLoadError onLoadError,
                                      int context) {
        ExpressBannerAd *instance = [[ExpressBannerAd alloc] init];
        
        CGFloat newWidth = width/[UIScreen mainScreen].scale;
        CGFloat newHeight = height/[UIScreen mainScreen].scale;
                 
        //重新为newWidth赋值为当前屏幕宽度,赋值后banner广告的宽度固定为当前屏幕宽度
        newWidth = [UIScreen mainScreen].bounds.size.width;
        newHeight = newWidth / 640 * 100;

        if (0) {
            instance.bannerView = [[BUNativeExpressBannerView alloc] initWithSlotID:[[NSString alloc] initWithUTF8String:slotID] rootViewController:GetAppController().rootViewController adSize:CGSizeMake(newWidth, newHeight) IsSupportDeepLink:YES interval:30];
        } else {
            instance.bannerView = [[BUNativeExpressBannerView alloc] initWithSlotID:[[NSString alloc] initWithUTF8String:slotID] rootViewController:GetAppController().rootViewController adSize:CGSizeMake(newWidth, newHeight) IsSupportDeepLink:YES];
        }
        instance.bannerView.frame = CGRectMake(0, CGRectGetHeight([UIScreen mainScreen].bounds)-newHeight, newWidth, newHeight);
        instance.bannerView.delegate = instance;
        instance.onLoad = onLoad;
        instance.onLoadError = onLoadError;
        instance.loadContext = context;
        [instance.bannerView loadAdData];
        
        // 强持有,是引用加+1
        [[BUToUnityAdManager sharedInstance] addAdManager:instance];
        
        (__bridge_retained void*)instance;
    }
    void UnionPlatform_ExpressBannersAd_Show(void* expressAdPtr, float originX, float originY) {
        ExpressBannerAd *expressBannerAd = (__bridge ExpressBannerAd*)expressAdPtr;
        
        CGFloat newX = originX/[UIScreen mainScreen].scale;
        CGFloat newY = originY/[UIScreen mainScreen].scale;
        
        //重新计算banner广告的位置
        //底部:
        newX = 0;
        newY = [UIScreen mainScreen].bounds.size.height - expressBannerAd.bannerView.frame.size.height;

        expressBannerAd.bannerView.frame = CGRectMake(newX, newY, expressBannerAd.bannerView.frame.size.width, expressBannerAd.bannerView.frame.size.height);
        
        [GetAppController().rootViewController.view addSubview:expressBannerAd.bannerView];
    }

或者unity2019以上的,也可以直接在unity中找到相应的脚本,修改再编译。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266