質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.23%

Unity : AndroidアプリでGoogleAdmobのリワード広告を実装したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,077

japomondo

score 15

実現したいこと

Unityで開発中のAndroidアプリで、GoogleAdmobのリワード広告を実装したい

詳細

UnityでAndroidのゲームを作っています。

キャラクターの体力が0になった時にリワード広告の視聴をユーザーに問い、視聴した場合体力を50%回復、視聴しなかった或いは視聴を途中で辞めた場合体力は回復せずゲームオーバーになる、という機能を実装したいと考えています。

上記について、理解が足りておらず以下の問題を抱えております。もしお力をお貸しくださる方がいらっしゃいましたら、アドバイス等いただけますと大変幸いです。

問題点

(1)HandleRewardBasedVideoRewardedメソッドが呼ばれるタイミングが分からない
→広告動画を最後まで見た上で右上の×ボタンをタップしても、リワードが与えられない(体力を50%回復するメソッドが呼ばれない)

(2)ユーザーが動画の視聴を途中で見るのを辞めた際に呼ばれる処理をどこに書けばいいか分からない
→HandleRewardBasedVideoClosedメソッドに書けばいいのかと思ったが、違った

(3)広告動画の再生時間を任意に選びたいが、方法が分からない
→5秒版、30秒版、60秒版とあると思いますが、表示する動画の長さを設定したい

該当のソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
using System;
using StrOpe = StringOperationUtil.OptimizedStringOperation;
using UniRx;
using UniRx.Triggers;

public class AdManagement : MonoBehaviour {

    private RewardBasedVideoAd rewardBasedVideo;
    // 呼びたいメソッドを持つクラス
    public PlayerHealth playerHealth;

    void Start ()
    {
        this.rewardBasedVideo = RewardBasedVideoAd.Instance;
         RequestRewardBasedVideo ();
        RegistHandler ();

        // 追記
        this.UpdateAsObservable()
              .Where(_ => endPlay)
              .ObserveOnMainThread()
              .Subscribe(_ => playerHealth.Revival());
    }

    private void RequestRewardBasedVideo()
    {
        #if UNITY_ANDROID
                // テストアカウント
                string adUnitId = "ca-app-pub-3940256099942544/5224354917";
        #else
                string adUnitId = "unexpected_platform";
        #endif

    AdRequest request = new AdRequest.Builder().Build();
    rewardBasedVideo.LoadAd(request, adUnitId);
    }

    private void RegistHandler()
    {
    // Ad event fired when the rewarded video ad

        // has been received.
    rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
    // has failed to load.
    rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
    // is opened.
    rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
    // has started playing.
    rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
    // has rewarded the user.
    rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
    // is closed.
    rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;
    // is leaving the application.
    rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication;
    }

    #region RewardBasedVideo callback handlers

    private void HandleRewardBasedVideoLoaded (object sender, EventArgs args)
    {
        MonoBehaviour.print ("HandleRewardBasedVideoLoaded event received");
    }

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

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

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

    // 広告動画が完全に視聴された際に呼び出されるメソッドと理解。キャラクターの体力を50%回復させたい
    private void HandleRewardBasedVideoRewarded (object sender, Reward args)
    {
        // 追記
        endPlay = true;

        string type = args.Type;
        double amount = args.Amount;
        MonoBehaviour.print (
            StrOpe.i + "HandleRewardBasedVideoRewarded event received for " + amount.ToString () + " " + type);
    }

    public void HandleRewardBasedVideoClosed (object sender, EventArgs args)
    {
        // 追記→コメントアウト
        // playerHealth.Death();
        MonoBehaviour.print ("HandleRewardBasedVideoClosed event received");
    }

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

    // キャラクターの体力が0になった時に、広告を見るか否かユーザーに問い、見る選択をした際に呼び出す
    public void PlayAd ()
    {
      if (rewardBasedVideo.IsLoaded()) {
        rewardBasedVideo.Show();
      }
    }

}

参考にしたエントリ

https://stackoverflow.com/questions/37354039/how-to-check-if-an-advertisement-has-finished-in-unity

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

リワードが与えられない

「体力を50%回復するメソッド」でUnity APIにアクセスしていませんか?
Unity APIはシングルスレッドです。Admobは別スレッドで動作しているのでその影響で動作しないかと思います。

方法は2つ思いつきます。

1 Update内でフラグをチェックする

ポイントは広告を閉じるタイミングで報酬を与えることです。
そうしないと広告を閉じる前に報酬を与えてしまうのでそれを防ぎます。
そして広告を再生するタイミングでTime.timeScaleを0にしてUnityの時間を止めることで余計な処理が走らないようにすると良いと思います。

bool IsReworded;
bool IsClosed;

void Update()
{
    if(IsReworded && IsClosed)
    {
        IsReworded = false;
        IsClosed = false;

        //ここで報酬を与える処理を実行
    }
}

void HandleRewardBasedVideoOpened(object sender, EventArgs args)
{
    Time.timeScale = 0;
}

void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
    IsReworded = true;
}

void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
    IsClosed = true;
    Time.timeScale = 1;
}

2 UnirxのObserveOnMainThread()を使う

Unirxにはメインスレッドに戻すObserveOnMainThread()というメソッドがあります。実は、これを試したことが無いのですがこれを介すことで問題なく動くと思います。

(2)について

一度今回のものを実装してみてください。

(3)について

Admobでは再生時間を選べません。他広告会社で選べるところがありますのでAdmobメディエーションを利用して広告を読み込むと良いと思います。ちなみにですが、Admobも含め各広告会社は1日の再生回数が大体決まっています。なのでAdmobのみではなく2,3社入れておくのをお勧めします。再生時間を選べる広告会社はVungleです。

最後に 動画広告の注意点

1 ダウンロード速度
例えばユーザーの端末に速度制限が掛かっている場合や、Wifiが不安定な場合広告の読み込みができないこともあります。その現象が続くとユーザーが離れてしまう原因になるので00秒待機しても動画の準備が終わらない場合、読み込み完了までインタースティシャルを表示することを検討してみてもいいかもしれません。

2 初期化が遅い
広告会社にもよりますが、初期化に1分以上掛かることもあります。ユーザーがわかりやすいように「準備中です」などの表記をすることをお勧めします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/23 18:52

    事例アプリまでご紹介いただき誠にありがとうございます。プレイして勉強させていただきます。

    (2)についてですが、ユーザーが動画の視聴を途中でやめてしまった場合に呼び出すメソッドは、どこにどのように書けば良いのか教えていただけませんでしょうか?

    キャンセル

  • 2018/01/23 19:21

    動画を見たかどうかで判定するといいと思います。クローズのタイミングで動画を見ていれば報酬を与える、見ていなければゲームオーバーといった感じです。

    フラグで処理してもいいですし、Unirxで書いてもいいと思います。

    キャンセル

  • 2018/01/23 19:57

    Unirxでできました!(1)と同じやり方でやれば良いだけでした…。本当にありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る