@ReWire_92

AdMob Rewarded Video. Что я делаю не так?

Есть 2 сцены - menu и game. При первом запуске приложения, всё работает, как часы. Реклама грузится, показывается, все события обрабатываются в хэндлерах. Но, стоит только покинуть вторую сцену, выйдя в меню и вернуться в неё обратно - все хэндлеры событий перестают срабатывать. AdMob больше не реагирует ни на одно событие, как-будто хэндлеров нет.

Вот код:
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;
	}
}


При первом запуске сцены всё работает:
LhyGBu7.png

При втором уже не обрабатывается ни один хэндлер:

1xkyCAk.pngnpnNqjz.png

Всё делал по инструкции из оффициального видео гугла:
видео

В общем, долго не мог понять, что происходит, пока тут не наткнулся на статью от тех же гуглов, где расписана реализация rewarded video в юнити. Тут, в отличие от видео, уже появляется вот такая поправка:
// 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.


Видимо ошибка кроется где-то здесь. Сцена 2 удаляется, синглтон остаётся, а его хэндлеры дублируются при повторной загрузке сцены, поэтому ничего и не работает.
Хорошо, я попробовал добавить себе такую проверку, как в коде выше:
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 ();
	}


Но мне это всё-равно не помогло. Хэндлеры после повторной загрузки сцены не работают. Что я делаю не так?
  • Вопрос задан
  • 2537 просмотров
Решения вопроса 1
@ReWire_92 Автор вопроса
Проблема решается, если в OnDestroy() отписаться от хэндлеров эвентов.

void OnDestroy(){
		videoAD.OnAdLoaded -= HandleOnAdLoaded;
		videoAD.OnAdFailedToLoad -= HandleOnAdFailedToLoad;
		videoAD.OnAdOpening -= HandleOnAdOpening;
		videoAD.OnAdStarted -= HandleOnAdStarted;
		videoAD.OnAdClosed -= HandleOnAdClosed;
		videoAD.OnAdRewarded -= HandleOnAdRewarded;
		videoAD.OnAdLeavingApplication -= HandleOnAdLeavingApplication;
	}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
MrMureno
@MrMureno Куратор тега Unity
VR for all
Создавайте все эти синглтоны для рекламы, статистики и прочее подобное в одной сцене самой первой стартовой (какой нибудь SingltonLoader ). которая не будет повторно грузится (а при загрузке не будет создаваться еще один дубликат объектов для доступа к апи)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы