はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Unity2018.2.6f1でAdmobの動画リワードを実装してみた

はじめに

以前Androidアプリを作っていた際にAdMobの動画リワードをしようと思ったときに結構時間がかかってしまいました。
そこで、なるべく細かい説明をせずにすぐに導入できるように手順を書いていきたいと思います。

環境

Unity2018.2.6f1

手順

AdMobのUnityプラグインを入れる

Get Started  |  Unity  |  Google Developers

Admobのバナーと動画リワードのどっちもこれでOKです。


※バージョンが古いとエラーがでてしまう可能性があります。
【Unity】AdmobでCannot find candidate artifact for com.google.android.gms:play-services-ads-lite:[11.0.4]というエラーが出たときの対処法 - はなちるのマイノート

AdMobRewardクラスを作成する

これらのサイトを参考に以下のコードを作りました。
http://wannabe-jellyfish.hatenablog.com/entry/2017/05/08/132855
https://teratail.com/questions/82446
https://developers.google.com/admob/unity/rewarded-video?hl=ja

using System;
using UnityEngine;
using GoogleMobileAds.Api;
using System.Collections;

public class AdMobReward : MonoBehaviour
{
    private string adUnitId = "ここに自分のIDを入れる";
    private AdRequest adRequest;
    private RewardBasedVideoAd rewardBasedVideo;
    private Action rewardedHandler;
    private static bool rewardBasedEventHandlersSet = false;

    static public AdMobReward instance;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }


    // Use this for initialization
    void Start()
    {
        RequestRewardBasedVideo();
    }

    private void RequestRewardBasedVideo()
    {
        rewardBasedVideo = RewardBasedVideoAd.Instance;

        // Create an empty ad request.
        adRequest = new AdRequest.Builder()
            .AddTestDevice(AdRequest.TestDeviceSimulator)       // Simulator.
            .Build();

        // Reward based video instance is a singleton. Register handlers once to avoid duplicate events.
        if (!rewardBasedEventHandlersSet)
        {
            rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;          // ad has been received.
            rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;    // ad has failed to load.
            rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;          // ad is opened.
            rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;         // ad has started playing.
            rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;        // ad has rewarded the user.
            rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;          // ad is closed.
            rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication; // ad is leaving the application.

            rewardBasedEventHandlersSet = true;
        }

        // Load
        rewardBasedVideo.LoadAd(adRequest, adUnitId);
    }


    public void Show(Action handler)
    {
        if (rewardBasedVideo.IsLoaded())
        {
            rewardedHandler = handler;
            rewardBasedVideo.Show();
        }
    }

    public void HandleRewardBasedVideoLoaded(object sender, EventArgs args) { }
    public void HandleRewardBasedVideoFailedToLoad(object sender, EventArgs args) {
        StartCoroutine(_waitConnectReward());
    }
    public void HandleRewardBasedVideoOpened(object sender, EventArgs args) { }
    public void HandleRewardBasedVideoStarted(object sender, EventArgs args) { }

    public void HandleRewardBasedVideoRewarded(object sender, Reward args)
    {
        //報酬受け取り時の処理
        rewardedHandler();
        StartCoroutine(_waitConnectReward());
}

    public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
    {
        //動画を閉じたときに、次の動画を読み込む
        if (!rewardBasedVideo.IsLoaded())
        {
            rewardBasedVideo.LoadAd(adRequest, adUnitId); // Load
        }
    }

    public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args) { }

    // ロードに失敗した場合、1秒待ってから再ロードをする
    IEnumerator _waitConnectReward()
    {
        while (true)
        {
            yield return new WaitForSeconds(1.0f);

            // 通信ができない場合は、リロードしない
            if (Application.internetReachability != NetworkReachability.NotReachable)
            {
                RequestRewardBasedVideo();
                break;
            }


        }
    }

}

ついでにAdmobManagerというGameObjectをタイトルのみに作成してAdMobRewardをアタッチしましょう。

動画を表示する

任意のクラスで表示したいところに以下のコードを入れます。

AdMobReward.instance.Show(() =>
        {
             //ここに動画を無事に視聴し終わったときの処理を書く
        });
動画リワードの注意点

動画を表示させるラムダ式の中身で、どうやらメソッドを呼び出すとクラッシュしてしまう?
https://teratail.com/questions/88110
そこでなにかしらのフラグを用意して、Update内で処理を実行させるようにしたら無事私の端末ではクラッシュしませんでした。

さいごに

以上の手順で無事動画リワードを実装することができました。
初めはなかなかとっつきづらい(私だけ?)ですが、やっぱり動画リワードがあるのとないので収益に結構差がでてしまうのでまだ実装したことがない人は一度挑戦してみてはどうでしょうか!