[Unity] AdMobの広告プレースメントでモバイルアプリ内広告を実装する

# はじめに
AdMobのプラグインには比較的少なめのコードで広告を実装できる「広告プレースメント」という機能があります。
これによって従来の方法に比べてかなり手軽に広告を表示させられるのですが、調べてみても意外と情報が見当たらないので本記事で使い方を解説してみようと思います。

とはいえ公式ガイドもかなり読みやすく書かれているため、ガイドに沿って実装すれば基本的に問題ないと思います。そのため、本記事はどちらかというと紹介に寄せた内容となっております。困ったら公式ガイドを読みましょう。

※広告プレースメント機能は2021/07/14時点で**試験運用版**となっています。

# 前提条件
公式ガイドに記載されている前提条件を参照。
https://developers.google.com/admob/unity/ad-placements?hl=ja
https://developers.google.com/admob/unity/quick-start?hl=ja#prerequisites
 
ただし、すでに通常のMobile Ads Unityプラグインを導入している場合は、一度消してから広告プレースメントのページの「ダウンロード」からパッケージを落としましょう。
**※プロジェクトにインポートする前に必ずバックアップを取りましょう。**


- 筆者の環境
 - Unity 2020.3.1f1 (対象PlatformをAndroidとしています）
 - Windows 10 2004

#### 目標
バナー・インターステイシャル・リワードのテスト広告表示

# 解説
解説用にこのようなプロジェクトを作成しました。
「インターステイシャル」を押すとインターステイシャル広告、「リワード」を押すとリワード広告が表示されるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/8d724cd2-7168-9d27-a726-b262e9f37118.png)

`Assets> Google Mobile Ads> Ad Placements` を開くと、インスペクタに広告プレースメントの一覧が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/6c335739-cab0-9519-e08e-f214c31e691c.png)
インポート時に最初から入っているのは全てテスト広告になっているので、今回はこれらをそのまま使用します。本番広告にする場合はUnit IDを本番用に変えればOKです。

### 広告の初期化
広告を設置する前に、SDKを初期化するようにしましょう。基本的にはタイトル画面の`Start`などで以下を実行させておけばOKです。

~~~cs:AdInitializer.cs
using GoogleMobileAds.Api;
using UnityEngine;

public class AdInitializer : MonoBehaviour
{
    public void Start()
    {
        // Initialize the Mobile Ads SDK.
        MobileAds.Initialize((initStatus) =>
        {
            // SDK initialization is complete
        });
    }
}
~~~

---

### バナー広告の設置
バナー広告は従来の方法だとインターステイシャルなどより若干面倒でしたが、広告プレースメントではeditor上でサクッと実装できます。
　
`GameObject> Google Mobile Ads> Banner Ad`を選択すると、ヒエラルキー上に「Banner Ad」オブジェクトが作成されます。
「AdGameObject の名前はすべて固有の名前にしてください」と書いてあるので、オブジェクト名は変えておきましょう。今回は「TestBannerAd」にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/26937b9c-01e5-f8c1-de04-e15027f8c123.png)
インスペクタからバナーの表示形式を設定できます。今回はSizeをBanner (320×50)、Ad PositionをTopにします。
これでPlayモードにすればバナー広告が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/37db4508-a9d8-f7ad-16be-e1680688d015.png)
完

---

### インターステイシャル広告の設置
`GameObject> Google Mobile Ads> Interstitial Ad`を選択すると、ヒエラルキー上に「Interstitial Ad」オブジェクトが作成されます。
「AdGameObject の名前はすべて固有の名前にしてください」と書いてあるので、オブジェクト名は変えておきましょう。今回は「TestInterstitialAd」にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/6ec75827-9a6d-6bea-9ab8-c7d84cc17981.png)

以下のスクリプトをインターステイシャルボタンに紐づけます。

~~~cs:InterstitialButton.cs
using UnityEngine;
using GoogleMobileAds.Api;
using GoogleMobileAds.Placement;

public class InterstitialButton : MonoBehaviour
{
    [SerializeField] GameObject _interstitialText;

    InterstitialAdGameObject _interstitialAd;

    private void Start()
    {
        // シーン内から広告オブジェクトを名前で取得
        _interstitialAd = MobileAds.Instance
            .GetAd<InterstitialAdGameObject>("TestInterstitialAd");

        // 広告を読み込む
        _interstitialAd.LoadAd();
    }

    // インターステイシャルボタン押下時のコールバック
    public void OnClick()
    {
        // 広告が読み込まれていれば表示する
        _interstitialAd.ShowIfLoaded();
    }

    // 広告を閉じた場合のコールバック
    public void OnAdClosed()
    {
        // 今回はテキストを表示する
        ShowText();
    }

    public void ShowText()
    {
        _interstitialText.SetActive(true);
    }
}
~~~

今回は`Start`で広告オブジェクトを取得していますが、[SerializeField]属性を使ってインスペクタから紐づけても大丈夫です。
`OnClick`はボタンのコールバックに紐づけておきましょう。

広告オブジェクトのインスペクタを見るとこちらにもコールバックを紐づける箇所があるので、ここに広告を閉じた場合に処理させたいメソッドを紐づけておきます。（今回は`OnAdClosed`）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/e0d38160-0094-c1f9-9502-d8f079040576.png)

また今回は`Start`で明示的に広告を読み込んでいるため、自動読み込みはOffにしておきます。
![スクリーンショット 2021-07-15 001616.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/e8c707a7-eddb-bd3f-0abb-d32eb34100df.jpeg)


これでPlayモードにし、インターステイシャルボタンを押せば広告が表示され、閉じると`OnAdClosed`が実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/29545e49-fa1a-0527-eaa2-c07d27179052.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/20389535-f4d4-37ef-63ea-ce9cc47c94a7.png)

完

---

### リワード広告の設置
`GameObject> Google Mobile Ads> Rewarded Ad`を選択すると、ヒエラルキー上に「Rewarded Ad」オブジェクトが作成されます。
「AdGameObject の名前はすべて固有の名前にしてください」と書いてあるので、オブジェクト名は変えておきましょう。今回は「TestRewardedAd」にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/ec242e55-eeb5-dee1-89c9-c38194f83092.png)

以下のスクリプトをリワードボタンに紐づけます。

~~~cs:RewardButton.cs
using UnityEngine;
using GoogleMobileAds.Api;
using GoogleMobileAds.Placement;

public class RewardButton : MonoBehaviour
{
    [SerializeField] GameObject _rewardText; // 広告視聴後に表示するオブジェクト

    RewardedAdGameObject _rewardedAd;

    void Start()
    {
        // シーン内から広告オブジェクトを名前で取得
        _rewardedAd = MobileAds.Instance
            .GetAd<RewardedAdGameObject>("TestRewardedAd");

        // 広告を読み込む
        _rewardedAd.LoadAd();
    }

    // リワードボタン押下時のコールバック
    public void OnClick()
    {
        // 広告が読み込まれていれば表示する
        _rewardedAd.ShowIfLoaded();
    }

    // リワード広告を最後まで観た場合のコールバック
    public void OnUserEarnedReward(Reward reward)
    {
        // 今回はテキストを表示する
        ShowText();
    }

    private void ShowText()
    {
        _rewardText.SetActive(true);
    }
}
~~~
今回は`Start`で広告オブジェクトを取得していますが、[SerializeField]属性を使ってインスペクタから紐づけても大丈夫です。
`OnClick`はボタンのコールバックに紐づけておきましょう。

広告オブジェクトのインスペクタを見るとこちらにもコールバックを紐づける箇所があるので、ここに広告を最後まで観た場合に報酬を受け取るためメソッドを紐づけておきます。（今回は`OnUserEarnedReward`）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/ec71a536-83f4-0667-ef20-bfda386c32d5.png)

また今回は`Start`で明示的に広告を読み込んでいるため、自動読み込みはOffにしておきます。![スクリーンショット 2021-07-15 003310.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/72943c83-d7c5-6d6b-7cdf-62a51c493276.jpeg)

これでPlayモードにし、リワードボタンを押せば広告が表示され、最後まで観て閉じると`OnUserEarnedReward`が実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/33dc72e3-3583-dd4c-3a38-7c2ff432c438.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764512/d76d923d-4b0a-9f9c-ae25-48d0b0eed9cb.png)

今回は省略しましたが、`OnAdFailedToLoad`でリワードボタンを消す処理なども入れておくと良いでしょう。

完

---

ぱっと見ても従来に比べてコードの記述量がかなり少なくなっていると思います（バナーに至っては初期化以外ノーコード！）。コールバックもインスペクタから紐づけられるなどUnityらしい実装ができるため、とても使い勝手が良いです。

筆者は広告プレースメントを使用したアプリを1つリリースし、現在準備しているアプリでも使用していますが、特にトラブルに見舞われることなくスムーズに実装を進めることができています。現在はまだ試験運用版の機能ではありますが、アプリ内広告の実装が億劫になっている方は利用してみてはいかがでしょうか。（そして早く正式リリースされてほしいと願うばかりです）