R
R
ReWire_922017-08-18 20:52:35
C++ / C#
ReWire_92, 2017-08-18 20:52:35

AdMob Rewarded Video. What am I doing wrong?

There are 2 scenes - menu and game. When you first launch the application, everything works like clockwork. Advertising is loaded, shown, all events are processed in handlers. But, as soon as you leave the second scene, go to the menu and go back to it - all event handlers stop working. AdMob no longer responds to any event, as if there are no handlers.
Here is the code:

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

public class RewardedVideo : MonoBehaviour {

  private const string admob_id = "/****тут мой id******/";
  private RewardBasedVideoAd videoAD;
  public GameObject Wait;
  public GameObject NoAdsFoundDialog;
  public Text ErrorMessage;
  public Console console;
  bool isAdLoading = false;
  bool ad_ready = false;
  bool failed = false;
  
  void Start () {
    videoAD = RewardBasedVideoAd.Instance;
    
    videoAD.OnAdLoaded += HandleOnAdLoaded;
    videoAD.OnAdFailedToLoad += HandleOnAdFailedToLoad;
    videoAD.OnAdOpening += HandleOnAdOpening;
    videoAD.OnAdStarted += HandleOnAdStarted;
    videoAD.OnAdClosed += HandleOnAdClosed;
    videoAD.OnAdRewarded += HandleOnAdRewarded;
    videoAD.OnAdLeavingApplication += HandleOnAdLeavingApplication;
    
    console.Print ("Trying to LoadVideoAd at Start()");
    LoadVideoAd ();
  }

  public void LoadVideoAd(){
    videoAD.LoadAd (new AdRequest.Builder ()
      .AddTestDevice (AdRequest.TestDeviceSimulator)
      .AddTestDevice (SystemInfo.deviceUniqueIdentifier.ToUpper())
      .Build (), admob_id);

    isAdLoading = true;
    console.Print ("Trying to LoadVideoAd");
    
  }

  public void Prepare(){
    Wait.SetActive (true);
  }

  public void showAd(){
    
    if (failed) {
      console.Print ("FAILED! Suspended until next request.");
      LoadVideoAd ();
      return;
    }

    if (ad_ready) {
      console.Print ("Trying to show video Ad");
      videoAD.Show ();
    }

    if (isAdLoading & !ad_ready & !failed) {
      console.Print ("Ad not loaded yet.");
      Invoke ("showAd", 3);
    }

    if(!isAdLoading & !ad_ready & !failed){
      console.Print ("No current requests found. Building new request");
      LoadVideoAd ();
      Invoke ("showAd", 4);
    }

  }
    
  public void HandleOnAdLoaded (object sender, EventArgs args){
    console.Print ("Ad Loaded! Ready to show");
    isAdLoading = false;
    ad_ready = true;
  }

  public void HandleOnAdFailedToLoad (object sender, AdFailedToLoadEventArgs args){
    isAdLoading = false;
    failed = true;
    console.Print ("Ad failed to load. Possible no network connection");
    switch (args.Message) {
    case "Network Error":
      ErrorMessage.text = "Не удалось подключиться к интернету. Проверьте соединение и повторите попытку";
      break;
    case "No fill":
      ErrorMessage.text = "Нет доступной к показу рекламы на данный момент. Попробуйте позже";
      break;
    default:
      ErrorMessage.text = args.Message + "\n" + "Попробуйте позже";
      break;
    }

    NoAdsFoundDialog.SetActive (true);
  }

  public void CloseErrorDialog(){
    NoAdsFoundDialog.SetActive (false);
    Wait.SetActive (false);
  }

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

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

  public void HandleOnAdClosed (object sender, EventArgs args){
    Wait.SetActive (false);
    console.Print ("HandleOnAdClosed was executed");
    ad_ready = false;
    LoadVideoAd ();
  }

  public void HandleOnAdRewarded (object sender, Reward args){
    console.Print ("Ad succesfully shown");
    console.Print("Gainded: " + ((int)(args.Amount)).ToString() + " " + args.Type);
    ad_ready = false;
  }

  public void HandleOnAdLeavingApplication(object sender, EventArgs args){
    Wait.SetActive (false);
    isAdLoading = false;
    ad_ready = false;
  }
}

At the first launch of the scene, everything works:
LhyGBu7.png
At the second time, not a single handler is processed:
1xkyCAk.pngnpnNqjz.png
I did everything according to the instructions from the official Google video:
video
In general, for a long time I could not understand what was happening until I came across an article from the same Google where implementation of rewarded video in the unit. Here, unlike the video, the following amendment already appears:
// Reward based video instance is a singleton. Register handlers once to
// avoid duplicate events.
if (!rewardBasedEventHandlersSet)
{
    // 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;

    rewardBasedEventHandlersSet = true;
}

Since a rewarded video instance is a singleton object, we recommend registering for ad events only once to avoid duplicate events.

Apparently the error lies somewhere here. Scene 2 is deleted, the singleton remains, and its handlers are duplicated when the scene is reloaded, so nothing works.
Okay, I tried to add myself such a check as in the code above:
public class RewardedVideo : MonoBehaviour {

  private const string admob_id = "/****тут мой id******/";
  private RewardBasedVideoAd videoAD;
  public GameObject Wait;
  public GameObject NoAdsFoundDialog;
  public Text ErrorMessage;
  public Console console;
  bool isAdLoading = false;
  bool ad_ready = false;
  bool failed = false;
  public static bool isHandlers = false;

  void Start () {
    videoAD = RewardBasedVideoAd.Instance;

    if (!isHandlers) {
      videoAD.OnAdLoaded += HandleOnAdLoaded;
      videoAD.OnAdFailedToLoad += HandleOnAdFailedToLoad;
      videoAD.OnAdOpening += HandleOnAdOpening;
      videoAD.OnAdStarted += HandleOnAdStarted;
      videoAD.OnAdClosed += HandleOnAdClosed;
      videoAD.OnAdRewarded += HandleOnAdRewarded;
      videoAD.OnAdLeavingApplication += HandleOnAdLeavingApplication;
      isHandlers = true;
    }

    console.Print ("Trying to LoadVideoAd at Start()");
    LoadVideoAd ();
  }

But it still didn't help me. Handlers after reloading the scene do not work. What am I doing wrong?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
ReWire_92, 2017-08-19
@ReWire_92

The problem is solved if in OnDestroy() unsubscribe from event handlers.

void OnDestroy(){
    videoAD.OnAdLoaded -= HandleOnAdLoaded;
    videoAD.OnAdFailedToLoad -= HandleOnAdFailedToLoad;
    videoAD.OnAdOpening -= HandleOnAdOpening;
    videoAD.OnAdStarted -= HandleOnAdStarted;
    videoAD.OnAdClosed -= HandleOnAdClosed;
    videoAD.OnAdRewarded -= HandleOnAdRewarded;
    videoAD.OnAdLeavingApplication -= HandleOnAdLeavingApplication;
  }

D
Denis Gaydak, 2017-08-18
@MrMureno

Create all these singletons for advertising, statistics, and so on in one scene of the very first start scene (some kind of SingltonLoader ). which will not be reloaded (and when loaded, another duplicate object will not be created to access the api)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question