Unity + Admob rewarded ads : event not firing - unity3d

I am stuck with admob rewarded ads, i can't figurate how to make event working. The problem is that my quiz game reload the scene every questions and even if i prevent the ad from destroy, the event are not firing at all. The ads are showing perfectly. I have tried multiple things but i must make a mistake somewhere... Anyone have an idea ?
Thank you very much!
using System;
using System.Collections;
using UnityEngine;
using GoogleMobileAds.Api;
public class RewardedScriptRow : MonoBehaviour
{
private RewardBasedVideoAd rewardBasedVideo;
public AudioClip GiftSound;
// Use this for initialization
void Start()
{
RequestInterstitial();
Debug.Log("Load at start");
}
public void LaunchAd() //Called from another script
{
StartCoroutine("Load");
}
private void RequestInterstitial()
{
string adUnitId = "";
#if UNITY_ANDROID
adUnitId = "ca-app-pub-00000/00000000";
#elif UNITY_IOS
adUnitId = "ca-app-pub-0000000000000";
#else
adUnitId = "unexpected_platform";
#endif
// Get singleton reward based video ad reference.
this.rewardBasedVideo = RewardBasedVideoAd.Instance;
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
this.rewardBasedVideo.LoadAd(request, adUnitId);
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoClosed;
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
}
IEnumerator Load()
{
while (!rewardBasedVideo.IsLoaded())
yield return new WaitForEndOfFrame();
yield return new WaitForSeconds(0.0f);
rewardBasedVideo.Show();
yield break;
}
//EVENT
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
RequestInterstitial();
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
RequestInterstitial();
}
}
EDIT 1 :
using System;
using System.Collections;
using UnityEngine;
using GoogleMobileAds.Api;
public class RewardedScriptRow : MonoBehaviour
{
private RewardBasedVideoAd rewardBasedVideo;
public AudioClip GiftSound;
public static RewardedScriptRow Instance;
// Use this for initialization
void Start()
{
Instance = this;
DontDestroyOnLoad(this);
RequestRewardBasedVideo();
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoClosed;
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
}
//Called after 10 questions
public void LaunchAd()
{
StartCoroutine("Load");
}
private void RequestRewardBasedVideo()
{
string adUnitId = "";
#if UNITY_ANDROID
adUnitId = "ca-app-pub-0000000/0000000000";
#elif UNITY_IOS
adUnitId = "ca-app-pub-00000/00000000";
#else
adUnitId = "unexpected_platform";
#endif
// Get singleton reward based video ad reference.
this.rewardBasedVideo = RewardBasedVideoAd.Instance;
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
this.rewardBasedVideo.LoadAd(request, adUnitId);
}
//EVENT
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
RequestRewardBasedVideo();
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
RequestRewardBasedVideo();
}
IEnumerator Load()
{
while (!rewardBasedVideo.IsLoaded())
yield return new WaitForEndOfFrame();
yield return new WaitForSeconds(0.0f);
rewardBasedVideo.Show();
yield break;
}
}
And this how the game work with the scenes :
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

First of all:
It seems very unwise/ illogical to call the RequestInterstial method in your event. Because by doing so, you are creating multiple subscriptions to the same events that you are already subscribed to! This can lead to very undesired/ unwanted behaviour as well as leading to Stackoverflow exceptions
It is unclear to me why you would even call RequestInterstial when the event fires. It seems to me that you would want to load a new video after the first one has been shown. Refactor your method so that you do not add the subscription events.
Move the subscription events and initialization code to your Start or Awake method.
Also you are not requesting an interstial, but a rewardbasedvideo. I'd suggest renaming to keep the code logical.
Public static RewardedScriptRow Instance;
void Start()
{
Instance = this;
DontDestroyOnLoad(this);
RequestRewardBasedVideo();
// Get singleton reward based video ad reference.
this.rewardBasedVideo = RewardBasedVideoAd.Instance;
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoClosed;
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
}
private void RequestRewardBasedVideo()
{
#if UNITY_ANDROID
string appId = "ca-app-pub-3940256099942544~3347511713";
#elif UNITY_IPHONE
string appId = "ca-app-pub-3940256099942544~1458002511";
#else
string appId = "unexpected_platform";
#endif
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the rewarded video ad with the request.
this.rewardBasedVideo.LoadAd(request, adUnitId);
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
RequestRewardBasedVideo();
}
Other than that, it should work. If you are still not getting the desirable result, try setting breakpoints while debugging and/ or use Debug.Log() inside the subscribed methods to see what's happening.
Edit: Also, if it is happening because of reloading scenes, you could try adding DontDestroyOnLoad(this); to prevent the "AdObject" from getting destroyed. I'd suggest creating this script in your very first scene and removing it from all others (to prevent duplicates).
You can then even apply the singleton pattern so you can easily access the script from within other classes.
Example:
StartCoroutine(RewardedScriptRow.Instance.LaunchAd());

Related

how to make this code in google play closed test

this code is perfectly working in unity editor but when I try it in google play closed test it does not work because there are no ad displayed so my bool to pause my player stay true and the player did not move
public class InterstitialAd : MonoBehaviour
{
public string androidAdUnitId;
public string iosAdUnitId;
IInterstitialAd interstitialAd;
async void Start()
{
// Initialize the package to access API
await UnityServices.InitializeAsync();
// Instantiate an interstitial ad object with platform
if (Application.platform == RuntimePlatform.Android)
{
interstitialAd = MediationService.Instance.CreateI
}
else if (Application.platform == RuntimePlatform.IPhon
{
interstitialAd = MediationService.Instance.CreateI
}
if UNITY_EDITOR
else
{
interstitialAd = MediationService.Instance.CreateI
}
endif
// Subscribe callback methods to load events:
interstitialAd.OnLoaded += AdLoaded;
interstitialAd.OnFailedLoad += AdFailedToLoad;
// Subscribe callback methods to show events:
interstitialAd.OnShowed += AdShown;
interstitialAd.OnFailedShow += AdFailedToShow;
interstitialAd.OnClosed += AdClosed;
interstitialAd.Load();
Debug.Log("try LoadAd");
}
private void AdClosed(object sender, EventArgs e)
{
Debug.Log("Ad has closed");
StartBTNBehaviour.pause = false; //this bool control the player movement false = player
//move
// Execute logic after an ad has been closed.
}
public void ShowAd()
{
// Ensure the ad has loaded, then show it.
Debug.Log("try ShowAd");
if (interstitialAd.AdState == AdState.Loaded)
{
interstitialAd.Show();
Debug.Log("ShowAd");
}
else
{
Debug.Log("Failed ShowAd");
StartBTNBehaviour.pause = false; //added to test
}
so my problem is no ads in google closed test which make my pause bool not changed

The gameobject has been destroyed but you are still trying to access it

I am trying to make a unity ad so that when the player loses, he can watch an ad to continue. However, when i change scenes and try to watch the ad again, it shows the gameobject which is the HeartMenu.SetActive(false) has been destroyed but you are still trying to access it but my script just sets the heart menu to SetActive(false). How can i go around this?
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Advertisements;
public class RewardedAdsButton : MonoBehaviour,
IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] Button _showAdButton;
[SerializeField] string _androidAdUnitId =
"Rewarded_Android";
[SerializeField] string _iOSAdUnitId = "Rewarded_iOS";
string _adUnitId = null; // This will remain null for
unsupported platforms
public GameObject Restart;
public GameObject HeartMenu;
void Awake()
{
#if UNITY_IOS
_adUnitId = _iOSAdUnitId;
#elif UNITY_ANDROID
_adUnitId = _androidAdUnitId;
#endif
}
public void Update()
{
}
// Load content to the Ad Unit:
public void LoadAd()
{
// IMPORTANT! Only load content AFTER initialization (in this example, initialization is handled in a different script).
Debug.Log("Loading Ad: " + _adUnitId);
Advertisement.Load(_adUnitId, this);
}
// If the ad successfully loads, add a listener to the button and enable it:
public void OnUnityAdsAdLoaded(string adUnitId)
{
Debug.Log("Ad Loaded: " + adUnitId);
if (adUnitId.Equals(_adUnitId))
{
// Configure the button to call the ShowAd() method when clicked:
_showAdButton.onClick.AddListener(ShowAd);
// Enable the button for users to click:
_showAdButton.interactable = true;
}
}
// Implement a method to execute when the user clicks the button:
public void ShowAd()
{
// Disable the button:
_showAdButton.interactable = false;
// Then show the ad:
Advertisement.Show(_adUnitId, this);
}
// Implement the Show Listener's OnUnityAdsShowComplete callback method to determine if the user gets a reward:
public void OnUnityAdsShowComplete(string adUnitId, UnityAdsShowCompletionState showCompletionState)
{
if (adUnitId.Equals(_adUnitId) && showCompletionState.Equals(UnityAdsShowCompletionState.COMPLETED))
{
Debug.Log("Unity Ads Rewarded Ad Completed");
// Grant a reward.
HeartMenu.SetActive(false);
OnDestroy();
Time.timeScale = 1f;
// Load another ad:
Advertisement.Load(_adUnitId, this);
}
}

Text not changing after rewarded video ad finished in Admob

I am implementing Admob into my android unity game. For now I am testing the rewarded video ad.
I added a ui text and wanted the text to change after the rewarded video has finished playing.
But after the video finishes playing and I close the video, the text is not changing.
Here is my script:
private RewardBasedVideoAd rewardBasedVideo;
public Text text;
// Start is called before the first frame update
void Start()
{
RequestReward();
}
private void RequestReward()
{
string adUnitId;
adUnitId = "ca-app-pub-3940256099942544/5224354917";
//rewardedAd = new RewardedAd(adUnitId);
rewardBasedVideo = RewardBasedVideoAd.Instance;
AdRequest request = new AdRequest.Builder().Build();
// Load the rewarded video ad with the request.
this.rewardBasedVideo.LoadAd(request, adUnitId);
}
public void DisplayRewardAd()
{
if (rewardBasedVideo.IsLoaded())
rewardBasedVideo.Show();
}
public void HandleRewardBasedVideoLoaded(object sender, EventArgs args)
{
rewardBasedVideo.Show();
}
public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
RequestReward();
}
public void HandleRewardBasedVideoOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoOpened event received");
}
public void HandleRewardBasedVideoStarted(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoStarted event received");
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
text.text = "Done!";
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
text.text = "Done!";
}
public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoLeftApplication event received");
}
private void OnEnable()
{
HandleRewardedAdEvents(true);
}
private void OnDisable()
{
HandleRewardedAdEvents(false);
}
void HandleRewardedAdEvents(bool subscribe)
{
if (subscribe)
{
// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
// Called when the ad is closed.
rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;
// Called when the ad click caused the user to leave the application.
rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication;
}
else
{
// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded -= HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad -= HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening -= HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted -= HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded -= HandleRewardBasedVideoRewarded;
// Called when the ad is closed.
rewardBasedVideo.OnAdClosed -= HandleRewardBasedVideoClosed;
// Called when the ad click caused the user to leave the application.
rewardBasedVideo.OnAdLeavingApplication -= HandleRewardBasedVideoLeftApplication;
}
}
EDIT: I forgot to add HandleRewardedAdEvents method to the question.
Ok now that you added the implementaion of HandleRewardedAdEvents I would change my answer and note that OnEnable is executed before Start so to a moment when rewardBasedVideo probably doesn't exist yet.
So I would rather add the callbacks in
private void RequestReward()
{
string adUnitId;
adUnitId = "ca-app-pub-3940256099942544/5224354917";
//rewardedAd = new RewardedAd(adUnitId);
rewardBasedVideo = RewardBasedVideoAd.Instance;
AdRequest request = new AdRequest.Builder().Build();
// ADD THE CALLBACKS
HandleRewardedAdEvents(true);
// Load the rewarded video ad with the request.
this.rewardBasedVideo.LoadAd(request, adUnitId);
}
Usually yes, you should remove any callback that isn't needed anymore. But in this case I would rather do it in
private void OnDestroy()
{
HandleRewardedAdEvents(false);
}
Not every time in OnEnable and OnDisable.
And use
private void HandleRewardedAdEvents(bool subscribe)
{
// NOTE that it is always secure to first remove callbacks
// even if not added yet
// this makes sure they are definitely only added once
// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded -= HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad -= HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening -= HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted -= HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded -= HandleRewardBasedVideoRewarded;
// Called when the ad is closed.
rewardBasedVideo.OnAdClosed -= HandleRewardBasedVideoClosed;
// Called when the ad click caused the user to leave the application.
rewardBasedVideo.OnAdLeavingApplication -= HandleRewardBasedVideoLeftApplication;
if (!subscribe) return;
// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
// Called when the ad is closed.
rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;
// Called when the ad click caused the user to leave the application.
rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication;
}

How to Show Admob Interstitials on Counted Click?

I am trying to something like this:
if button clicked for 4 times, I could show Interstitial?
However i couldn't make it happen.
Created a game object.
Attached script to that object.
Created a restart button.
Implemented this object on that button with onclick-runtime only etc.
Now every time user clicks restart button, interstitial ads show itself. but of course as you might know, it is very annoying.
I dont know how to count how many times users press the restart button and for example show the ads every 3 or 4 times if user press the button.
Thank you.
using UnityEngine;
using System.Collections;
using GoogleMobileAds.Api;
public class AdScript : MonoBehaviour
{
InterstitialAd interstitial;
public string InterstitialId;
// Use this for initialization
void Start()
{
//Request Ads
//RequestBanner();
RequestInterstitial();
}
public void showInterstitialAd()
{
//Show Ad
if (interstitial.IsLoaded())
{
interstitial.Show();
}
}
private void RequestInterstitial()
{
string adUnitId = InterstitialId;
// Initialize an InterstitialAd.
interstitial = new InterstitialAd(adUnitId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
interstitial.LoadAd(request);
}
}
I can give you idea ,you can use time class to know last showed ad or use variable saying like every 4 game show ad on restart button click.
using UnityEngine;
using System.Collections;
using GoogleMobileAds.Api;
public class AdScript : MonoBehaviou
{
int counter =0;
InterstitialAd interstitial;
public string InterstitialId;
// Use this for initialization
void Start()
{
//Request Ads
//RequestBanner();
RequestInterstitial();
}
public void showInterstitialAd()
{
counter ++;
if(counter%4==0)
{
//Show Ad
if (interstitial.IsLoaded())
{
interstitial.Show();
}
}
}
private void RequestInterstitial()
{
string adUnitId = InterstitialId;
// Initialize an InterstitialAd.
interstitial = new InterstitialAd(adUnitId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
interstitial.LoadAd(request);
}
}

Unity2D: Admob - Reward system

I'm having problems with my code, you see I imported Google Admob into my project. I integrated the reward system into my AdManager script, using Github's Plugin Wiki and Documentation. However (in my AdManager script) my rewarding the user function isn't really working, I have a static int from another script that gives my player a boomerang when they pick it up in the game, buy it or receive from watching a video. Below is my AdManager script:
public class AdManager : MonoBehaviour
{
public static AdManager Instance { set; get; }
public string bannerId;
public string videoId;
private void Start()
{
Instance = this;
DontDestroyOnLoad(gameObject);
#if UNITY_EDITOR
#elif UNITY_ANDROID
Admob.Instance().initAdmob(bannerId, videoId);
Admob.Instance().setTesting(true);
Admob.Instance().loadInterstitial();
Admob.Instance().rewardedVideoEventHandler += onRewardedVideoEvent;
#endif
}
public void Reward()
{
Admob ad = Admob.Instance();
if (ad.isRewardedVideoReady())
{
ad.showRewardedVideo();
}
else
{
ad.loadRewardedVideo("ca-app-pub-2099082167446861/xxxxxxxxxx");
}
}
void onRewardedVideoEvent(string eventName, string msg)
{
WeaponScript.boomerang += 1;
Debug.Log("Well Done! You have been rewarded one Boomerang!");
Debug.Log("handler onRewardedVideoEvent---" + eventName + " " + msg);
}
}
My problem: I built the game and tried it out, watched a video got a reward (boomerang), but when I did it again (watch another reward video) I didn't get another reward (boomerang). Not sure if I'm doing it wrong. Please can anyone help me with my problem. Thank you!