2.GoogleAdMob--Google广告 SDK

这几天忙着项目接入各种SDK,终于快忙完了。总结一波笔记。
GoogleAdMob是Google推出来的广告SDK,用于轻中度游戏的广告变现。
首先给出官方网站:https://admob.google.com/home/ (去这个网站给你的游戏创建GameID和广告ID)
然后给出开发者网站:https://developers.google.cn/admob/unity/start (这里会逐步讲解如何接入SDK)
当然,上面的两个网站都需要富强哈。
接下来我也做下笔记,如何接入GoogleAd的三种类型的广告(原生广告暂时不管);不能富强的朋友也可以看我的笔记。

先总结一下基本流程:
获取Game ID --> 实例化SDK --> 请求相应的类型广告 --> 获取相应类型广告ID --> 创建广告实例
--> 发起请求广告 --> 显示广告(判断是否请求成功) ---> 每种类型广告都会有一些相应的回调方法

注意:使用下面显示的标记将您的AdMob 应用ID添加 到Unity应用目录中的AndroidManifest.xml文件中。您可以在AdMob用户界面中找到您的应用ID。用于在引号中插入您自己的AdMob App ID。自Google移动广告SDK版本17.0.0起,以下步骤是必需的。无法添加此<meta-data>标记会导致邮件崩溃: "The Google Mobile Ads SDK was initialized incorrectly."

<manifest>
    <application>
        <!-- Your AdMob App ID will look similar to this
        sample ID: ca-app-pub-3940256099942544~3347511713 -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="[ADMOB_APP_ID]"/>
    </application>
</manifest>

1.Banner 横幅广告

横幅广告是在屏幕上占据一处位置的矩形图片或文字广告。用户与应用互动时,这类广告会停留在屏幕上,并且可在一段时间后自动刷新。

using GoogleMobileAds.Api;
using System;
using UnityEngine;
public class AdController : MonoBehaviour {

    private BannerView bannerView;

    public string bannerAndID = "ca-app-pub-3940256099942544/6300978111";
    public string bannerIosId = "ca-app-pub-3940256099942544/2934735716";

    void Start () {
        string appId = "unexpected_platform";
#if UNITY_ANDROID
         appId = "ca-app-pub-3940256099942544~3347511713";
#elif UNITY_IPHONE
         appId = "ca-app-pub-3940256099942544~1458002511";
#endif
        //初始化 Google Mobile Ads SDK.
        MobileAds.Initialize(appId);
        RequestBanner();
    }

    /// <summary>
    /// 请求Banner广告
    /// </summary>
    public void RequestBanner()
    {
        string adUnitId = "unexpected_platform";
#if UNITY_ANDROID
        adUnitId = bannerAndID;
#elif UNITY_IPHONE
        adUnitId = bannerIosID;
#endif

        //实例化Banner
        // adUnitId - BannerView加载广告单元的ID
        // AdSize - Banner广告的相关尺寸(如果尺寸太大,可能Banner不会显示)
        // AdPosition - banner广告显示的位置(枚举类型)
        bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Top);

        // 广告加载完成后调用
        bannerView.OnAdLoaded += HandleOnAdLoadedBanner;
        // 广告加载失败时调用
        bannerView.OnAdFailedToLoad += HandleOnAdFailedToLoadBanner;
        //当广告被点击时调用(记录 跟踪用户点击率的好地方)
        bannerView.OnAdOpening += HandleOnAdOpenedBanner;
        // 当玩家观看完广告后,点击返回游戏时调用(可以使用此方法恢复暂停的活动,或执行任何其他必要的操作,以做好互动准备。)
        bannerView.OnAdClosed += HandleOnAdClosedBanner;
        // 当玩家点击打开了其他应用程序(如Google Play)时调用(也就是点击广告跳转出去当前游戏了)
        bannerView.OnAdLeavingApplication += HandleOnAdLeavingApplicationBanner;

        // 创建一个请求
        AdRequest request = new AdRequest.Builder().Build();

        //通过请求去加载Banner. 
        bannerView.LoadAd(request);
    }

    //显示Banner
    public void ShowBanner()
    {
        bannerView.Show();
    }

    //隐藏Banner
    public void HideBanner()
    {
        bannerView.Hide();
    }

    #region Banner广告的回调函数
    public void HandleOnAdLoadedBanner(object sender, EventArgs args)
    {
        print("HandleAdLoaded event received");
    }

    public void HandleOnAdFailedToLoadBanner(object sender, AdFailedToLoadEventArgs args)
    {
        print("HandleFailedToReceiveAd event received with message: "+ args.Message);
    }

    public void HandleOnAdOpenedBanner(object sender, EventArgs args)
    {
        print("HandleAdOpened event received");
    }

    public void HandleOnAdClosedBanner(object sender, EventArgs args)
    {
        print("HandleAdClosed event received");
    }

    public void HandleOnAdLeavingApplicationBanner(object sender, EventArgs args)
    {
        print("HandleAdLeavingApplication event received");
    }
    #endregion
}

注意:Banner加载后可自行显示Banner广告,ShowBanner()方法不是必须的,这个方法主要是对应HideBanner()方法的(便于隐藏后再次显示)。--2018.12.13 踩坑后再次更新笔记

Banner广告的尺寸和位置可以进行自定义

//自定义显示位置(原点是屏幕的左上角)
BannerView bannerView = new BannerView(adUnitId, AdSize.Banner, 0, 50);

//自定义尺寸
AdSize adSize = new AdSize(250, 250);
BannerView bannerView = new BannerView(adUnitId, adSize, AdPosition.Bottom);

//智能横幅广告(智能横幅广告会“智能”地检测设备当前屏幕方向的宽度,并据此设置与之等宽的广告视图,从而解决不同设备间屏幕尺寸不同的问题。)
BannerView bannerView = new BannerView(adUnitId, AdSize.SmartBanner, AdPosition.Top);

2.Interstitial 插页广告

插页式广告是覆盖其主机应用界面的全屏广告。它们通常显示在应用程序流程中的自然转换点,例如在游戏中各级别之间的暂停期间。当应用显示插页式广告时,用户可以选择点按广告并继续其目的地或关闭广告并返回应用。

using GoogleMobileAds.Api;
using System;
using UnityEngine;
public class AdController : MonoBehaviour {

    private InterstitialAd interstitial;

    public string InterstitialAndID = "ca-app-pub-3940256099942544/1033173712";
    public string InterstitialIosAD = "ca-app-pub-3940256099942544/4411468910";

    void Start () {
        string appId = "unexpected_platform";
#if UNITY_ANDROID
         appId = "ca-app-pub-3940256099942544~3347511713";
#elif UNITY_IPHONE
         appId = "ca-app-pub-3940256099942544~1458002511";
#endif
        //初始化 Google Mobile Ads SDK.
        MobileAds.Initialize(appId);

    }

    /// <summary>
    /// 请求Interstitial广告
    /// </summary>
    public void RequestInterstitial()
    {
        string adUnitId = "unexpected_platform";
#if UNITY_ANDROID
        adUnitId = InterstitialAndID;
#elif UNITY_IPHONE
        adUnitId = InterstitialIosAD;
#endif

        //初始化InterstitialAd.
        interstitial = new InterstitialAd(adUnitId);
         //和banner类型的回调函数
        interstitial.OnAdLoaded += HandleOnAdLoadedInterstitial;
        interstitial.OnAdFailedToLoad += HandleOnAdFailedToLoadInterstitial;
        interstitial.OnAdOpening += HandleOnAdOpenedInterstitial;
        interstitial.OnAdClosed += HandleOnAdClosedInterstitial;
        interstitial.OnAdLeavingApplication += HandleOnAdLeavingApplicationInterstitial;

        // 创建一个请求.
        AdRequest request = new AdRequest.Builder().Build();
        // 通过请求去加载InterstitialAd.
        interstitial.LoadAd(request);
    }
    /*注意:在iOS上,InterstitialAd对象是一次性使用对象。
     * 这意味着,一旦显示插页式广告,该InterstitialAd对象就无法用于加载其他广告。
     * 要请求其他插页式广告,您需要创建一个新 InterstitialAd对象。*/

    /// <summary>
    /// 显示Interstitial广告
    /// </summary>
    public void ShowInterstitial() {
        if (interstitial.IsLoaded())
        {
            interstitial.Show();
        }
    }

    #region Interstitial广告的回调函数
    public void HandleOnAdLoadedInterstitial(object sender, EventArgs args)
    {
        print("HandleAdLoaded event received");
    }

    public void HandleOnAdFailedToLoadInterstitial(object sender, AdFailedToLoadEventArgs args)
    {
        print("HandleFailedToReceiveAd event received with message: "
                            + args.Message);
    }

    public void HandleOnAdOpenedInterstitial(object sender, EventArgs args)
    {
        print("HandleAdOpened event received");
    }

    public void HandleOnAdClosedInterstitial(object sender, EventArgs args)
    {
        print("HandleAdClosed event received");

        //当关闭一个Interstitial时,需要重新实例化一个
        if (interstitial != null)
        {
            interstitial.Destroy();
        }
        RequestInterstitial();
    }

    public void HandleOnAdLeavingApplicationInterstitial(object sender, EventArgs args)
    {
        print("HandleAdLeavingApplication event received");
    }
    #endregion
}

注意在iOS上,InterstitialAd对象是一次性使用对象。这意味着,一旦显示插页式广告,该InterstitialAd对象就无法用于加载其他广告。要请求其他插页式广告,需要创建一个新 InterstitialAd对象。

3.RewardVideo激励视频广告

奖励视频广告是全屏视频广告,用户可以选择全额观看, 以换取应用内奖励。
注意:RewardBasedVideoAd是单例

using GoogleMobileAds.Api;
using System;
using UnityEngine;
public class AdController : MonoBehaviour {

    private RewardBasedVideoAd rewardBasedVideo;

    public string RewardVideoAndID = "ca-app-pub-3940256099942544/5224354917";
    public string RewardVideoIosID = "ca-app-pub-3940256099942544/1712485313";

    void Start () {
        string appId = "unexpected_platform";
#if UNITY_ANDROID
         appId = "ca-app-pub-3940256099942544~3347511713";
#elif UNITY_IPHONE
         appId = "ca-app-pub-3940256099942544~1458002511";
#endif
        //初始化 Google Mobile Ads SDK.
        MobileAds.Initialize(appId);

        //RewardBasedVideoAd是单例
        rewardBasedVideo = RewardBasedVideoAd.Instance;

        //RewardVideo回调方法
        rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
        rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
        rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
        //广告开始播放时会调用此方法
        rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
        // 观看完视频获得奖励(Reward参数就是呈现给玩家的奖励)
        rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
        rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;
        rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication;
    }

    /// <summary>
    /// 请求RewardVideo
    /// </summary>
    public void RequestRewardVideo()
    {
        string adUnitId = "unexpected_platform";
#if UNITY_ANDROID
        adUnitId = RewardVideoAndID;
#elif UNITY_IPHONE
        adUnitId = RewardVideoIosID;        
#endif

        // 创建一个请求
        AdRequest request = new AdRequest.Builder().Build();
        // 根据请求去加载相关RewardVideo
        rewardBasedVideo.LoadAd(request, adUnitId);
    }

    /// <summary>
    /// 显示RewardVideo
    /// </summary>
    public void ShowRewardVideo() {
        if (rewardBasedVideo.IsLoaded())
        {
            rewardBasedVideo.Show();
        }
    }

    #region RewardVideo回调函数
    public void HandleRewardBasedVideoLoaded(object sender, EventArgs args)
    {
        print("HandleRewardBasedVideoLoaded event received");
    }

    public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
    {
        print(
            "HandleRewardBasedVideoFailedToLoad event received with message: "
                             + args.Message);
    }

    public void HandleRewardBasedVideoOpened(object sender, EventArgs args)
    {
        print("HandleRewardBasedVideoOpened event received");
    }

    public void HandleRewardBasedVideoStarted(object sender, EventArgs args)
    {
        print("HandleRewardBasedVideoStarted event received");
    }

    public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
    {
        print("HandleRewardBasedVideoClosed event received");
        //重新加载RewardVideo
        RequestRewardVideo();
    }

    public void HandleRewardBasedVideoRewarded(object sender, Reward args)
    {
        string type = args.Type;
        double amount = args.Amount;
        print(
            "HandleRewardBasedVideoRewarded event received for "
                        + amount.ToString() + " " + type);
    }

    public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args)
    {
        print("HandleRewardBasedVideoLeftApplication event received");
    }
    #endregion
}

总结
1.每一种广告都有相应的回调函数;可以通过这些回调函数做一些“事情”:跟踪用户点击率;重新加载广告;给与玩家一定的奖励等等。

2.无论是哪种广告,你可以使用Google提供的测试ID去测试,但是你不能用自己的应用创建的广告ID去测试。除非在Google那里备案了,你将使用一台测试设备去测试你的应用广告ID。(不按规则走,可能会被封号)

3.官方Demo:https://github.com/googleads/googleads-mobile-unity/tree/master/samples/HelloWorld

4.我的Demo: https://github.com/junyu-tu/Plugin-For-Unity/tree/master/GoogleAdmobDemo

5.使用Google测试ID走了一遍流程,如果发现RewardVideo不能播放,原因是:google 测试的广告ID 适用于海外,富强后就可以测试啦!!!

就是这样,我还会回来的!.png

2018.12.13 踩坑后更新:Banner加载后可自行显示Banner广告,ShowBanner()方法不是必须的,这个方法主要是对应HideBanner()方法的(便于隐藏后再次显示)。


2019.4.1号采坑:Google更新了一些东西,按照往常在Unity里面使用Admob后进行Ios打包,游戏会在Iphone上闪退,出现以下报错:

报错信息.png

点击蓝色的链接会发现跳转到了关于在IOS上使用Admob的教程之中(需要富强)
更新Info.png

对,你没有看错,需要在Info.plist文件里面添加广告对应的平台ID(注意:Android和Ios的不同);添加好后,再进行打包就会发现没有问题了。(嘚瑟脸!!!)


2019.8.20 踩坑后更新
1.关于Banner广告,如果Banner尺寸不匹配,在Android上可能不会显示出来,但是实际测试发现在Iphone一样的效果:如果Banner尺寸不匹配,则Banner广告无法显示出来。so使用Banner的智能尺寸:AdSize.SmartBanner。
2.由于之前游戏都不需要跳转场景,将AdManager作为单例处理没啥关系;但是当涉及到需要跳转场景的时候,需要对Banner的对象进行检测,如果存在就进行删除再重新创建,不然的话在重新跳转到游戏主界面场景会出现两个Banner广告。

// Clean up banner ad before creating a new one.
        if (this.bannerView != null)
        {
            this.bannerView.Destroy();
        }

2019.10.21踩坑后更新
关于RewardVideo用户没有观看完的处理;如果你的游戏里面仅仅只是通过RewardVideo来给予玩家奖励游戏金币,那么这个坑你踩不到;如果你将RewardVideo作为玩家在每一局死亡后的拯救方式之一可能就要注意了,因为Admob只有观看完视频的回调,然后就是Close Reward Video 回调,它并不会像Unity Ad给予你一个是否观看完的结果,如果一旦没观看完,你的拯救面板消失了,玩家就继续游戏了。这就是一个游戏逻辑bug,你得设置一个flag参数来标记玩家是否挂看完视频,然后在Close Reward Video回调里面进行相应的操作。
1.当玩家看完视频,跳转到HandleRewardBasedVideoRewarded回调,调用继续游戏函数,并且更改flag值,这个逻辑没问题。
2.当玩家没看完视频,你必须在HandleRewardBasedVideoClosed回调里面判断flag值是否发生改变,如果没有改变,表示这个RewardVideo并没有播放完,直接调用结束当局游戏的方法就OK。

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

推荐阅读更多精彩内容