這幾天忙著項(xiàng)目接入各種SDK,終于快忙完了??偨Y(jié)一波筆記。
GoogleAdMob是Google推出來的廣告SDK,用于輕中度游戲的廣告變現(xiàn)。
首先給出官方網(wǎng)站:https://admob.google.com/home/ (去這個(gè)網(wǎng)站給你的游戲創(chuàng)建GameID和廣告ID)
然后給出開發(fā)者網(wǎng)站:https://developers.google.cn/admob/unity/start (這里會(huì)逐步講解如何接入SDK)
當(dāng)然,上面的兩個(gè)網(wǎng)站都需要富強(qiáng)哈。
接下來我也做下筆記,如何接入GoogleAd的三種類型的廣告(原生廣告暫時(shí)不管);不能富強(qiáng)的朋友也可以看我的筆記。
先總結(jié)一下基本流程:
獲取Game ID --> 實(shí)例化SDK --> 請(qǐng)求相應(yīng)的類型廣告 --> 獲取相應(yīng)類型廣告ID --> 創(chuàng)建廣告實(shí)例
--> 發(fā)起請(qǐng)求廣告 --> 顯示廣告(判斷是否請(qǐng)求成功) ---> 每種類型廣告都會(huì)有一些相應(yīng)的回調(diào)方法
注意:使用下面顯示的標(biāo)記將您的AdMob 應(yīng)用ID添加 到Unity應(yīng)用目錄中的AndroidManifest.xml
文件中。您可以在AdMob用戶界面中找到您的應(yīng)用ID。用于在引號(hào)中插入您自己的AdMob App ID。自Google移動(dòng)廣告SDK版本17.0.0起,以下步驟是必需的。無法添加此<meta-data>標(biāo)記會(huì)導(dǎo)致郵件崩潰: "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 橫幅廣告
橫幅廣告是在屏幕上占據(jù)一處位置的矩形圖片或文字廣告。用戶與應(yīng)用互動(dòng)時(shí),這類廣告會(huì)停留在屏幕上,并且可在一段時(shí)間后自動(dòng)刷新。
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>
/// 請(qǐng)求Banner廣告
/// </summary>
public void RequestBanner()
{
string adUnitId = "unexpected_platform";
#if UNITY_ANDROID
adUnitId = bannerAndID;
#elif UNITY_IPHONE
adUnitId = bannerIosID;
#endif
//實(shí)例化Banner
// adUnitId - BannerView加載廣告單元的ID
// AdSize - Banner廣告的相關(guān)尺寸(如果尺寸太大,可能Banner不會(huì)顯示)
// AdPosition - banner廣告顯示的位置(枚舉類型)
bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Top);
// 廣告加載完成后調(diào)用
bannerView.OnAdLoaded += HandleOnAdLoadedBanner;
// 廣告加載失敗時(shí)調(diào)用
bannerView.OnAdFailedToLoad += HandleOnAdFailedToLoadBanner;
//當(dāng)廣告被點(diǎn)擊時(shí)調(diào)用(記錄 跟蹤用戶點(diǎn)擊率的好地方)
bannerView.OnAdOpening += HandleOnAdOpenedBanner;
// 當(dāng)玩家觀看完廣告后,點(diǎn)擊返回游戲時(shí)調(diào)用(可以使用此方法恢復(fù)暫停的活動(dòng),或執(zhí)行任何其他必要的操作,以做好互動(dòng)準(zhǔn)備。)
bannerView.OnAdClosed += HandleOnAdClosedBanner;
// 當(dāng)玩家點(diǎn)擊打開了其他應(yīng)用程序(如Google Play)時(shí)調(diào)用(也就是點(diǎn)擊廣告跳轉(zhuǎn)出去當(dāng)前游戲了)
bannerView.OnAdLeavingApplication += HandleOnAdLeavingApplicationBanner;
// 創(chuàng)建一個(gè)請(qǐng)求
AdRequest request = new AdRequest.Builder().Build();
//通過請(qǐng)求去加載Banner.
bannerView.LoadAd(request);
}
//顯示Banner
public void ShowBanner()
{
bannerView.Show();
}
//隱藏Banner
public void HideBanner()
{
bannerView.Hide();
}
#region Banner廣告的回調(diào)函數(shù)
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()方法不是必須的,這個(gè)方法主要是對(duì)應(yīng)HideBanner()方法的(便于隱藏后再次顯示)。--2018.12.13 踩坑后再次更新筆記
Banner廣告的尺寸和位置可以進(jìn)行自定義
//自定義顯示位置(原點(diǎn)是屏幕的左上角)
BannerView bannerView = new BannerView(adUnitId, AdSize.Banner, 0, 50);
//自定義尺寸
AdSize adSize = new AdSize(250, 250);
BannerView bannerView = new BannerView(adUnitId, adSize, AdPosition.Bottom);
//智能橫幅廣告(智能橫幅廣告會(huì)“智能”地檢測(cè)設(shè)備當(dāng)前屏幕方向的寬度,并據(jù)此設(shè)置與之等寬的廣告視圖,從而解決不同設(shè)備間屏幕尺寸不同的問題。)
BannerView bannerView = new BannerView(adUnitId, AdSize.SmartBanner, AdPosition.Top);
2.Interstitial 插頁廣告
插頁式廣告是覆蓋其主機(jī)應(yīng)用界面的全屏廣告。它們通常顯示在應(yīng)用程序流程中的自然轉(zhuǎn)換點(diǎn),例如在游戲中各級(jí)別之間的暫停期間。當(dāng)應(yīng)用顯示插頁式廣告時(shí),用戶可以選擇點(diǎn)按廣告并繼續(xù)其目的地或關(guān)閉廣告并返回應(yīng)用。
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>
/// 請(qǐng)求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類型的回調(diào)函數(shù)
interstitial.OnAdLoaded += HandleOnAdLoadedInterstitial;
interstitial.OnAdFailedToLoad += HandleOnAdFailedToLoadInterstitial;
interstitial.OnAdOpening += HandleOnAdOpenedInterstitial;
interstitial.OnAdClosed += HandleOnAdClosedInterstitial;
interstitial.OnAdLeavingApplication += HandleOnAdLeavingApplicationInterstitial;
// 創(chuàng)建一個(gè)請(qǐng)求.
AdRequest request = new AdRequest.Builder().Build();
// 通過請(qǐng)求去加載InterstitialAd.
interstitial.LoadAd(request);
}
/*注意:在iOS上,InterstitialAd對(duì)象是一次性使用對(duì)象。
* 這意味著,一旦顯示插頁式廣告,該InterstitialAd對(duì)象就無法用于加載其他廣告。
* 要請(qǐng)求其他插頁式廣告,您需要?jiǎng)?chuàng)建一個(gè)新 InterstitialAd對(duì)象。*/
/// <summary>
/// 顯示Interstitial廣告
/// </summary>
public void ShowInterstitial() {
if (interstitial.IsLoaded())
{
interstitial.Show();
}
}
#region Interstitial廣告的回調(diào)函數(shù)
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");
//當(dāng)關(guān)閉一個(gè)Interstitial時(shí),需要重新實(shí)例化一個(gè)
if (interstitial != null)
{
interstitial.Destroy();
}
RequestInterstitial();
}
public void HandleOnAdLeavingApplicationInterstitial(object sender, EventArgs args)
{
print("HandleAdLeavingApplication event received");
}
#endregion
}
注意:在iOS上,InterstitialAd對(duì)象是一次性使用對(duì)象。這意味著,一旦顯示插頁式廣告,該InterstitialAd對(duì)象就無法用于加載其他廣告。要請(qǐng)求其他插頁式廣告,需要?jiǎng)?chuàng)建一個(gè)新 InterstitialAd對(duì)象。
3.RewardVideo激勵(lì)視頻廣告
獎(jiǎng)勵(lì)視頻廣告是全屏視頻廣告,用戶可以選擇全額觀看, 以換取應(yīng)用內(nèi)獎(jiǎng)勵(lì)。
注意: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回調(diào)方法
rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
//廣告開始播放時(shí)會(huì)調(diào)用此方法
rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
// 觀看完視頻獲得獎(jiǎng)勵(lì)(Reward參數(shù)就是呈現(xiàn)給玩家的獎(jiǎng)勵(lì))
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;
rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication;
}
/// <summary>
/// 請(qǐng)求RewardVideo
/// </summary>
public void RequestRewardVideo()
{
string adUnitId = "unexpected_platform";
#if UNITY_ANDROID
adUnitId = RewardVideoAndID;
#elif UNITY_IPHONE
adUnitId = RewardVideoIosID;
#endif
// 創(chuàng)建一個(gè)請(qǐng)求
AdRequest request = new AdRequest.Builder().Build();
// 根據(jù)請(qǐng)求去加載相關(guān)RewardVideo
rewardBasedVideo.LoadAd(request, adUnitId);
}
/// <summary>
/// 顯示RewardVideo
/// </summary>
public void ShowRewardVideo() {
if (rewardBasedVideo.IsLoaded())
{
rewardBasedVideo.Show();
}
}
#region RewardVideo回調(diào)函數(shù)
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
}
總結(jié):
1.每一種廣告都有相應(yīng)的回調(diào)函數(shù);可以通過這些回調(diào)函數(shù)做一些“事情”:跟蹤用戶點(diǎn)擊率;重新加載廣告;給與玩家一定的獎(jiǎng)勵(lì)等等。
2.無論是哪種廣告,你可以使用Google提供的測(cè)試ID去測(cè)試,但是你不能用自己的應(yīng)用創(chuàng)建的廣告ID去測(cè)試。除非在Google那里備案了,你將使用一臺(tái)測(cè)試設(shè)備去測(cè)試你的應(yīng)用廣告ID。(不按規(guī)則走,可能會(huì)被封號(hào))
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測(cè)試ID走了一遍流程,如果發(fā)現(xiàn)RewardVideo不能播放,原因是:google 測(cè)試的廣告ID 適用于海外,富強(qiáng)后就可以測(cè)試?yán)玻。。?/p>
2018.12.13 踩坑后更新:Banner加載后可自行顯示Banner廣告,ShowBanner()方法不是必須的,這個(gè)方法主要是對(duì)應(yīng)HideBanner()方法的(便于隱藏后再次顯示)。
2019.4.1號(hào)采坑:Google更新了一些東西,按照往常在Unity里面使用Admob后進(jìn)行Ios打包,游戲會(huì)在Iphone上閃退,出現(xiàn)以下報(bào)錯(cuò):
點(diǎn)擊藍(lán)色的鏈接會(huì)發(fā)現(xiàn)跳轉(zhuǎn)到了關(guān)于在IOS上使用Admob的教程之中(需要富強(qiáng))
對(duì),你沒有看錯(cuò),需要在Info.plist文件里面添加廣告對(duì)應(yīng)的平臺(tái)ID(注意:Android和Ios的不同);添加好后,再進(jìn)行打包就會(huì)發(fā)現(xiàn)沒有問題了。(嘚瑟臉?。。。?p>
2019.8.20 踩坑后更新:
1.關(guān)于Banner廣告,如果Banner尺寸不匹配,在Android上可能不會(huì)顯示出來,但是實(shí)際測(cè)試發(fā)現(xiàn)在Iphone一樣的效果:如果Banner尺寸不匹配,則Banner廣告無法顯示出來。so使用Banner的智能尺寸:AdSize.SmartBanner。
2.由于之前游戲都不需要跳轉(zhuǎn)場(chǎng)景,將AdManager作為單例處理沒啥關(guān)系;但是當(dāng)涉及到需要跳轉(zhuǎn)場(chǎng)景的時(shí)候,需要對(duì)Banner的對(duì)象進(jìn)行檢測(cè),如果存在就進(jìn)行刪除再重新創(chuàng)建,不然的話在重新跳轉(zhuǎn)到游戲主界面場(chǎng)景會(huì)出現(xiàn)兩個(gè)Banner廣告。
// Clean up banner ad before creating a new one.
if (this.bannerView != null)
{
this.bannerView.Destroy();
}
2019.10.21踩坑后更新:
關(guān)于RewardVideo用戶沒有觀看完的處理;如果你的游戲里面僅僅只是通過RewardVideo來給予玩家獎(jiǎng)勵(lì)游戲金幣,那么這個(gè)坑你踩不到;如果你將RewardVideo作為玩家在每一局死亡后的拯救方式之一可能就要注意了,因?yàn)锳dmob只有觀看完視頻的回調(diào),然后就是Close Reward Video 回調(diào),它并不會(huì)像Unity Ad給予你一個(gè)是否觀看完的結(jié)果,如果一旦沒觀看完,你的拯救面板消失了,玩家就繼續(xù)游戲了。這就是一個(gè)游戲邏輯bug,你得設(shè)置一個(gè)flag參數(shù)來標(biāo)記玩家是否掛看完視頻,然后在Close Reward Video回調(diào)里面進(jìn)行相應(yīng)的操作。
1.當(dāng)玩家看完視頻,跳轉(zhuǎn)到HandleRewardBasedVideoRewarded回調(diào),調(diào)用繼續(xù)游戲函數(shù),并且更改flag值,這個(gè)邏輯沒問題。
2.當(dāng)玩家沒看完視頻,你必須在HandleRewardBasedVideoClosed回調(diào)里面判斷flag值是否發(fā)生改變,如果沒有改變,表示這個(gè)RewardVideo并沒有播放完,直接調(diào)用結(jié)束當(dāng)局游戲的方法就OK。