Using admob rewarded ad in unity singleton pattern - unity3d

I am using admob ads in my app and they are working fine. But when i try to do something after a ad close or reward earned call back my code breaks. Following is my adMob script
public class AdMobScript : MonoBehaviour
{
...
public event Action OnReviveRewardEarned;
public event Action OnReviveAdLoaded;
public event Action OnReviveAdClosed;
private void LoadReviveRewardedAd()
{
reviveRewardedAd = new RewardedAd(adReviveRewardedId);
reviveRewardedAd.OnAdLoaded += ReviveAdLoaded;
reviveRewardedAd.OnUserEarnedReward += ReviveEarnedReward;
reviveRewardedAd.OnAdClosed += ReviveAdClosed;
AdRequest request = new AdRequest.Builder().Build();
reviveRewardedAd.LoadAd(request);
}
private void ReviveAdClosed(object sender, EventArgs e)
{
LoadReviveRewardedAd();
if (isRewardErned)
{
isRewardErned = false;
OnReviveRewardEarned.Invoke();
}
else
OnReviveAdClosed.Invoke();
}
private void ReviveEarnedReward(object sender, Reward e)
{
isRewardErned = true;
}
private void ReviveAdLoaded(object sender, EventArgs e)
{
//reviveButton.interactable = true;
OnReviveAdLoaded.Invoke();
}
public void ShowAdToRevive()
{
if (reviveRewardedAd.IsLoaded())
{
reviveRewardedAd.Show();
}
}
...
}
In the callbacks i am calling my adManager script which is in term using adMob script. Here is the code for it.
public class AdManager : MonoBehaviour
{
...
private void Start() {
AdMobScript.instance.OnReviveAdClosed += ReviveAdClosed;
AdMobScript.instance.OnReviveAdLoaded += ReviveAdLoaded;
AdMobScript.instance.OnReviveRewardEarned += ReviveReward;
}
#region ReviveAds
private void ReviveReward() {
//game crash here
backButton.gameObject.SetActive(true);
reviveButton.gameObject.SetActive(false);
noThanksButton.gameObject.SetActive(false);
manager.Revive();
}
private void ReviveAdLoaded() {
reviveButton.interactable = true;
}
private void ReviveAdClosed() {
//game crash here
reviveButton.interactable = false;
}
public void ShowAdToRevive() {
AdMobScript.instance.ShowAdToRevive();
}
...
}
After either ad close or reward earned my game crashes (error log says
get_gameObject can only be called from the main thread
). There must be something i am doing wrong. Can anyone please point me to the right direction?

The reason for the problem - you trying to manipulate with MonoBehaviors, not in main thread.
Just write simple scheduler which calls the events in the Unity thread, like this:
Scheduler:
using System;
using UnityEngine;
public class Scheduler : MonoBehaviour
{
public static Scheduler instance;
public event Action secondTick = delegate { };
private float seconds = 0;
private void Awake()
{
instance = this;
}
private void Update()
{
seconds += Time.unscaledDeltaTime;
if (seconds >= 1.0f)
{
seconds -= 1.0f;
secondTick.Invoke();
}
}
}
Updated AdMobScript:
public class AdMobScript : MonoBehaviour
{
...
private bool onRewardEarnedCall = false;
private bool onRewardAdLoaded = false;
private bool onRewardAdClosed = false;
public event Action OnReviveRewardEarned;
public event Action OnReviveAdLoaded;
public event Action OnReviveAdClosed;
private void LoadReviveRewardedAd()
{
reviveRewardedAd = new RewardedAd(adReviveRewardedId);
reviveRewardedAd.OnAdLoaded += ReviveAdLoaded;
reviveRewardedAd.OnUserEarnedReward += ReviveEarnedReward;
reviveRewardedAd.OnAdClosed += ReviveAdClosed;
AdRequest request = new AdRequest.Builder().Build();
reviveRewardedAd.LoadAd(request);
Scheduler.instance.secondTick += OnSecondTick;
}
private void OnSecondTick()
{
if(onRewardAdClosed)
{
onRewardAdClosed = false;
OnReviveAdClosed.Invoke();
}
if(onRewardEarnedCall)
{
OnReviveRewardEarned.Invoke();
onRewardEarnedCall = false;
}
if(onRewardAdLoaded)
{
OnReviveAdLoaded.Invoke();
onRewardAdLoaded = false;
}
}
private void ReviveAdClosed(object sender, EventArgs e)
{
LoadReviveRewardedAd();
if (isRewardErned)
{
isRewardErned = false;
onRewardEarnedCall = true;
}
else
onRewardAdClosed = true;
}
private void ReviveEarnedReward(object sender, Reward e)
{
isRewardErned = true;
}
private void ReviveAdLoaded(object sender, EventArgs e)
{
//reviveButton.interactable = true;
onRewardAdLoaded = true;
}
public void ShowAdToRevive()
{
if (reviveRewardedAd.IsLoaded())
{
reviveRewardedAd.Show();
}
}
...
}
This is a very simple and not optimize solution but this will solve your problem.

Related

Ads are showing when I build a apk in unity but when app bundle is uploaded on playstore, it doesn't

I recently launched a game in unity which I uploaded on playstore. I was able to display ads when I just built an apk from the app but when I upload the app bundle on playstore and playstore launched that update, the ads stop displaying. My admob account is approved and my individual app's approval status is also 'Ready'.
I am not able to understand why my game is not displaying any ads as it should be working. All the ad ids are correct and it works fine in the normal apk. I am seeing proper ads.
Can someone help me please.
My AdManager Script
using GoogleMobileAds.Api;
using GoogleMobileAds.Common;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MediationManager : MonoBehaviour
{
#region Ad_IDs
public string app_Id;
public string banner_Id;
public string nativeBanner_Id;
public string interstitial_Id;
public string rewardedVideo_Id;
public static MediationManager Instance;
private BannerView bannerView;
private BannerView nativebannerView;
private InterstitialAd interstitial;
private RewardedAd rewardedAd;
#endregion
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(this);
print("again");
}
else
{
print("not again");
Destroy(this.gameObject);
}
}
// Start is called before the first frame update
void Start()
{
MobileAds.SetiOSAppPauseOnBackground(true);
//RequestConfiguration requestConfiguration =
// new RequestConfiguration.Builder()
// .SetTagForChildDirectedTreatment(TagForChildDirectedTreatment.True)
// .build();
//MobileAds.SetRequestConfiguration(requestConfiguration);
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(HandleInitCompleteAction);
}
private void HandleInitCompleteAction(InitializationStatus initstatus)
{
MobileAdsEventExecutor.ExecuteInUpdate(() =>
{
//RequestBanner();
RequestInterstitial();
RequestAdmobRewarded();
// RequestNativeBanner();
//ShowTopBanner();
});
}
#region Request Ads
public AdRequest CreateAdRequest()
{
return new AdRequest.Builder().Build();
}
private void RequestInterstitial()
{
if (PlayerPrefs.GetInt("adsRemoveCount") <= 2)
{
// Clean up interstitial ad before creating a new one.
if (this.interstitial != null)
{
this.interstitial.Destroy();
}
// Create an interstitial.
this.interstitial = new InterstitialAd(interstitial_Id);
// Register for ad events.
this.interstitial.OnAdLoaded += this.HandleOnAdLoaded;
this.interstitial.OnAdFailedToLoad += this.HandleOnAdFailedToLoad;
this.interstitial.OnAdOpening += this.HandleOnAdOpened;
this.interstitial.OnAdClosed += this.HandleOnAdClosed;
// this.interstitial. += this.HandleOnAdLeavingApplication;
// Load an interstitial ad.
this.interstitial.LoadAd(this.CreateAdRequest());
}
}
public void RequestBanner()
{
if (PlayerPrefs.GetInt("RemoveAds") == 0)
{
// Clean up banner ad before creating a new one.
if (this.bannerView != null)
{
this.bannerView.Destroy();
}
// Create a 320x50 banner at the top of the screen.
this.bannerView = new BannerView(banner_Id, AdSize.Banner, AdPosition.Top);
// Register for ad events.
this.bannerView.OnAdLoaded += this.HandleAdLoaded;
this.bannerView.OnAdFailedToLoad += this.HandleAdFailedToLoad;
this.bannerView.OnAdOpening += this.HandleAdOpened;
this.bannerView.OnAdClosed += this.HandleAdClosed;
//this.bannerView.OnAdLeavingApplication += this.HandleAdLeftApplication;
// Load a banner ad.
this.bannerView.LoadAd(this.CreateAdRequest());
this.bannerView.Hide();
print("Show Top Banner");
}
}
public void RequestNativeBanner()
{
if (PlayerPrefs.GetInt("RemoveAds") == 0)
{
if (this.nativebannerView != null)
{
this.nativebannerView.Destroy();
}
this.nativebannerView = new BannerView(banner_Id, AdSize.MediumRectangle, 0, 54);
this.nativebannerView.LoadAd(this.CreateAdRequest());
this.nativebannerView.Hide();
}
}
private void RequestAdmobRewarded()
{
if (PlayerPrefs.GetInt("adsRemoveCount") <= 2)
{
this.rewardedAd = new RewardedAd(rewardedVideo_Id);
// Called when an ad request has successfully loaded.
this.rewardedAd.OnAdLoaded += HandleRewardedAdLoaded;
// Called when an ad request failed to load.
// this.rewardedAd.OnAdFailedToLoad += HandleRewardedAdFailedToLoad;
// Called when an ad is shown.
this.rewardedAd.OnAdOpening += HandleRewardedAdOpening;
// Called when an ad request failed to show.
this.rewardedAd.OnAdFailedToShow += HandleRewardedAdFailedToShow;
// Called when the user should be rewarded for interacting with the ad.
this.rewardedAd.OnUserEarnedReward += HandleUserEarnedReward;
// Called when the ad is closed.
this.rewardedAd.OnAdClosed += HandleRewardedAdClosed;
// Load the rewarded ad with the request.
this.rewardedAd.LoadAd(this.CreateAdRequest());
}
}
#endregion
#region Banner callback handlers
public void HandleAdLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdLoaded event received");
}
public void HandleAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
MonoBehaviour.print("HandleFailedToReceiveAd event received with message: " + args.LoadAdError);
}
public void HandleAdOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdOpened event received");
}
public void HandleAdClosed(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdClosed event received");
}
public void HandleAdLeftApplication(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdLeftApplication event received");
}
#endregion
#region Interstial callback handlers
public void HandleOnAdLoaded(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleAdLoaded event received");
}
public void HandleOnAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
MonoBehaviour.print("HandleFailedToReceiveAd event received with message: "
+ args.ToString());
RequestInterstitial();
}
public void HandleOnAdOpened(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleAdOpened event received");
}
public void HandleOnAdClosed(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleAdClosed event received");
RequestInterstitial();
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void HandleOnAdLeavingApplication(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleAdLeavingApplication event received");
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
#endregion
#region AdmobRewarded_Ad callback handlers
public void HandleRewardedAdLoaded(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleRewardedAdLoaded event received");
}
public void HandleRewardedAdFailedToLoad(object sender, AdErrorEventArgs args)
{
MonoBehaviour.print(
"HandleRewardedAdFailedToLoad event received with message: "
+ args.AdError.GetMessage());
// RequestAdmobRewarded();
}
public void HandleRewardedAdOpening(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleRewardedAdOpening event received");
// RequestAdmobRewarded();
}
public void HandleRewardedAdFailedToShow(object sender, AdErrorEventArgs args)
{
MonoBehaviour.print(
"HandleRewardedAdFailedToShow event received with message: "
+ args.AdError.GetMessage());
// RequestAdmobRewarded();
}
public void HandleRewardedAdClosed(object sender, System.EventArgs args)
{
MonoBehaviour.print("HandleRewardedAdClosed event received");
RequestAdmobRewarded();
}
public void HandleUserEarnedReward(object sender, Reward args)
{
string type = args.Type;
double amount = args.Amount;
if (PlayerPrefs.HasKey("adsRemoveCount"))
{
PlayerPrefs.SetInt("adsRemoveCount", PlayerPrefs.GetInt("adsRemoveCount") + 1);
}
else
{
PlayerPrefs.SetInt("adsRemoveCount", 1);
}
}
#endregion
#region Ads Call Function
public void ShowAdmobInterstial()
{
if (PlayerPrefs.GetInt("adsRemoveCount") <= 2)
{
if (interstitial.IsLoaded())
{
interstitial.Show();
}
else
{
RequestInterstitial();
}
}
}
public void ShowAdmobRewardedVideo()
{
if (PlayerPrefs.GetInt("adsRemoveCount") <= 2)
{
if (this.rewardedAd.IsLoaded())
{
this.rewardedAd.Show();
}
else
{
RequestAdmobRewarded();
}
}
}
#endregion
}

How to check if unity video ads ready to show or loaded

I'm using Unity Ads in my game. In older version i check if unity video ads are ready to show then call a method to show ads like this
public bool IsVideoReady()
{
if (Advertisement.IsReady())
return true;
else
return false;
}
But in new version i dont know how to check if unity video ads are ready or loaded to show.
My new script is
using UnityEngine;
using UnityEngine.Advertisements;
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener, IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] string _androidGameId;
[SerializeField] string _iOSGameId;
string _gameId;
[SerializeField] bool _testMode = true;
private void Awake()
{
if (Advertisement.isInitialized)
{
Debug.Log("Advertisement is Initialized");
LoadRewardedAd();
}
else
{
InitializeAds();
}
}
public void InitializeAds()
{
_gameId = (Application.platform == RuntimePlatform.IPhonePlayer) ? _iOSGameId : _androidGameId;
Advertisement.Initialize(_gameId, _testMode, this);
}
public void OnInitializationComplete()
{
Debug.Log("Unity Ads initialization complete.");
LoadInerstitialAd();
LoadBannerAd();
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
public void LoadInerstitialAd()
{
Advertisement.Load("Interstitial_Android", this);
}
public void LoadRewardedAd()
{
Advertisement.Load("Rewarded_Android", this);
}
public void OnUnityAdsAdLoaded(string placementId)
{
Debug.Log("OnUnityAdsAdLoaded");
Advertisement.Show(placementId,this);
}
public void OnUnityAdsFailedToLoad(string placementId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error showing Ad Unit {placementId}: {error.ToString()} - {message}");
}
public void OnUnityAdsShowFailure(string placementId, UnityAdsShowError error, string message)
{
Debug.Log("OnUnityAdsShowFailure");
}
public void OnUnityAdsShowStart(string placementId)
{
Debug.Log("OnUnityAdsShowStart");
Time.timeScale = 0;
Advertisement.Banner.Hide();
}
public void OnUnityAdsShowClick(string placementId)
{
Debug.Log("OnUnityAdsShowClick");
}
public void OnUnityAdsShowComplete(string placementId, UnityAdsShowCompletionState showCompletionState)
{
Debug.Log("OnUnityAdsShowComplete "+showCompletionState);
if (placementId.Equals("Rewarded_Android") && UnityAdsShowCompletionState.COMPLETED.Equals(showCompletionState))
{
Debug.Log("rewared Player");
}
Time.timeScale = 1;
Advertisement.Banner.Show("Banner_Android");
}
public void LoadBannerAd()
{
Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
Advertisement.Banner.Load("Banner_Android",
new BannerLoadOptions
{
loadCallback = OnBannerLoaded,
errorCallback = OnBannerError
}
);
}
void OnBannerLoaded()
{
Advertisement.Banner.Show("Banner_Android");
}
void OnBannerError(string message)
{
}
}
i just want to know how to check if unity interstital or rewarded ads are ready before showing them.
because in new versions Advertisment.isReady() is not working any more

How can I communicate between classes in a Xamarin project?

How is it possible to communicate between two classes?
I have two classes, one is a stopwatch class and my second is my lifecircle events class "App"
class1:
public partial class Stopwatch : ContentPage
{
Stopwatch stopwatch;
bool isOn = false;
public Stopwatch()
{
InitializeComponent();
stopwatch = new Stopwatch();
labeltimer.Text = "00:00:00.00";
}
private void btnTimerReset(object sender, EventArgs e)
{
btnStart.Text = "Start";
stopwatch.Reset();
}
private void btnTimerstop(object sender, EventArgs e)
{
if (labeltimer.Text != "00:00:00.00")
btnStart.Text = "Resume";
stopwatch.Stop();
}
private void btnTimerStart(object sender, EventArgs e)
{
Timerstart();
isOn = true;
}
private void Timerstart()
{
stopwatch.Start();
Device.StartTimer(TimeSpan.FromMilliseconds(1), () =>
{
labeltimer.Text = stopwatch.Elapsed.ToString("hh\\:mm\\:ss\\.ff");
return true; // return true to repeat counting, false to stop timer
});
}
public bool isStopwatchEnabled()
{
if(isOn)
{
return true;
}
else
return false;
}
}
}
App Class
public partial class App : Application
{
bool isenableSW = false;
public App()
{
InitializeComponent();
DependencyService.Register<MockDataStore>();
MainPage = new AppShell();
{
};
}
protected override void OnSleep()
{
Stoppuhr tp = new Stoppuhr();
isenableSW = tp.isStopwatchEnabled();
if (isenablesw)
{
tp.Timerstart();
}
}
}
My problem is now, when I start my stopwatch my bool variable switches from false to true. That is what I want... when I trigger now the onSleep() function, it creates a new instance of my stopwatch class and next it should check if the stopwatch was enabled before onSleep() triggered, but my bool variable is always false because it has its standard value(= false). Makes sense... but how can I communicate between these classes correctly?
I guess I found a solution. The value doesn't change when I do this:
bool isOn = false -> static bool isOn = false;

How to fix "interstitialAd.IsLoaded() returns true in offline" (unity C#)

interstitialAd.IsLoaded() is always returning true even if device is offline. its works fine when app device is online.
public class InsAdBanner : MonoBehaviour
{
public int SceneIndex;
private InterstitialAd interstitialAd;
void Start()
{
this.RequestInterstitial();
}
void RequestInterstitial()
{
string interstitial_ID = "ad_id";
interstitialAd = new InterstitialAd(interstitial_ID);
if (this.interstitialAd != null)
{
this.interstitialAd.Destroy();
}
this.interstitialAd.OnAdLoaded += HandleOnAdLoaded;
this.interstitialAd.OnAdFailedToLoad += HandleOnAdFailedToLoad;
this.interstitialAd.OnAdOpening += HandleOnAdOpened;
this.interstitialAd.OnAdClosed += HandleOnAdClosed;
this.interstitialAd.OnAdLeavingApplication += HandleOnAdLeavingApplication;
AdRequest adRequest = new AdRequest.Builder().Build();
interstitialAd.LoadAd(adRequest);
}
public void Display_InterstitialAD()
{
<!-- plz see this line below -->
if (interstitialAd.IsLoaded())
{
Debug.Log("interstitialAd " + interstitialAd.IsLoaded());
interstitialAd.Show();
}
else {
getOut();
}
}
public void getOut() {
interstitialAd.Destroy();
SceneManager.LoadScene(SceneIndex);
restertAdCounter.restertsAdCouner += 1;
}
#region Interstitial callback handlers
//Handle event
public void HandleOnAdLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdLoaded event received");
}
public void HandleOnAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
RequestInterstitial();
}
public void HandleOnAdOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdOpened event received");
}
public void HandleOnAdClosed(object sender, EventArgs args)
{
SceneManager.LoadScene(SceneIndex);
}
public void HandleOnAdLeavingApplication(object sender, EventArgs args)
{
SceneManager.LoadScene(SceneIndex);
}
#endregion
void OnDisable()
{
this.interstitialAd.OnAdLoaded += HandleOnAdLoaded;
this.interstitialAd.OnAdFailedToLoad += HandleOnAdFailedToLoad;
this.interstitialAd.OnAdOpening += HandleOnAdOpened;
this.interstitialAd.OnAdClosed += HandleOnAdClosed;
this.interstitialAd.OnAdLeavingApplication += HandleOnAdLeavingApplication;
}
void OnDestroy()
{
interstitialAd.Destroy();
}
}
I expecting it to return false in offline..it is working fine when app device is online .. but creates this problem when device is offline..plz help.. i cant find any solution in google.
Edit: Its not working on online too.. after adding real ad in place of test ad this problem is occurring.
Solved my problem by changing Minify->Relese->Proguard to Minify->Relese->None on player setting.(Although i dont know how actually its working)

Reward ad callback is not firing

i have a game and when the player loses their lives, i want them to be able to watch a video for a second chance.
I am using unity version 2018.1.1f1 person and i have downloaded the admob unity plugin version 3.13.1
So if the player agrees to watch an ad, the ad will play and then resume the game without firing the callback that rewards the player. This is my code:
using System;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.UI;
public class RewardAd : MonoBehaviour {
private BannerView bannerView;
private InterstitialAd interstitial;
private RewardBasedVideoAd rewardBasedVideo;
private float deltaTime = 0.0f;
private static string outputMessage = string.Empty;
public AudioSource musicPlayer;
public Player player;
public Text UIText;
public static string OutputMessage
{
set { outputMessage = value; }
}
public void Start()
{
#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
MobileAds.SetiOSAppPauseOnBackground(true);
// Initialize the Google Mobile Ads SDK.
MobileAds.Initialize(appId);
//Get singleton reward based video ad reference.
this.rewardBasedVideo = RewardBasedVideoAd.Instance;
// RewardBasedVideoAd is a singleton, so handlers should only be registered once.
this.rewardBasedVideo.OnAdLoaded += this.HandleRewardBasedVideoLoaded;
this.rewardBasedVideo.OnAdFailedToLoad += this.HandleRewardBasedVideoFailedToLoad;
this.rewardBasedVideo.OnAdOpening += this.HandleRewardBasedVideoOpened;
this.rewardBasedVideo.OnAdStarted += this.HandleRewardBasedVideoStarted;
this.rewardBasedVideo.OnAdRewarded += this.HandleRewardBasedVideoRewarded;
this.rewardBasedVideo.OnAdClosed += this.HandleRewardBasedVideoClosed;
this.rewardBasedVideo.OnAdLeavingApplication += this.HandleRewardBasedVideoLeftApplication;
}
public void Update()
{
// Calculate simple moving average for time to render screen. 0.1 factor used as smoothing
// value.
this.deltaTime += (Time.deltaTime - this.deltaTime) * 0.1f;
}
// Returns an ad request with custom ad targeting.
private AdRequest CreateAdRequest()
{
return new AdRequest.Builder()
.AddTestDevice(AdRequest.TestDeviceSimulator)
.AddTestDevice("0123456789ABCDEF0123456789ABCDEF")
.AddKeyword("game")
.SetGender(Gender.Male)
.SetBirthday(new DateTime(1985, 1, 1))
.TagForChildDirectedTreatment(false)
.AddExtra("color_bg", "9B30FF")
.Build();
}
private void RequestRewardBasedVideo()
{
#if UNITY_EDITOR
string adUnitId = "unused";
#elif UNITY_ANDROID
string adUnitId = "ca-app-pub-3940256099942544/5224354917";
#elif UNITY_IPHONE
string adUnitId = "ca-app-pub-7624023175090985/4535603801";
#else
string adUnitId = "unexpected_platform";
#endif
this.rewardBasedVideo.LoadAd(this.CreateAdRequest(), adUnitId);
}
private void ShowInterstitial()
{
if (this.interstitial.IsLoaded())
{
this.interstitial.Show();
}
else
{
MonoBehaviour.print("Interstitial is not ready yet");
}
}
private void ShowRewardBasedVideo()
{
if (this.rewardBasedVideo.IsLoaded())
{
this.rewardBasedVideo.Show();
}
else
{
MonoBehaviour.print("Reward based video ad is not ready yet");
}
}
#region RewardBasedVideo callback handlers
public void HandleRewardBasedVideoLoaded(object sender, EventArgs args)
{
this.rewardBasedVideo.Show();
UIText.text = "Watch a short video\nfor an extra life ?";
}
public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
UIText.text = "Watch a short video\nfor an extra life ?";
}
public void HandleRewardBasedVideoOpened(object sender, EventArgs args)
{
musicPlayer.Pause();
player.disableMovment = true;
}
public void HandleRewardBasedVideoStarted(object sender, EventArgs args)
{
musicPlayer.Pause();
player.disableMovment = true;
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
UIText.text = "Watch a short video\nfor an extra life ?";
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
player.rewardAdUI.SetActive(false);
UIText.text = "Watch a short video\nfor an extra life ?";
player.disableMovment = false;
if (PlayerPrefs.GetInt("music") == 1)
{
musicPlayer.Play();
}
Lives.addLives(1);
player.RespawnPlayer();
}
public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args)
{
UIText.text = "Watch a short video\nfor an extra life ?";
}
public void secondChance()
{
UIText.text = "Loading video...\nplease wait.";
this.RequestRewardBasedVideo();
}
public void GameOver()
{
player.disableMovment = false;
if (PlayerPrefs.GetInt("music") == 1)
{
musicPlayer.Play();
}
player.gameOver();
}
#endregion
}
So the 2nd to last function called secondChance() is what runs to play the ad. On my android device, this plays the test rewarded video.
After the ad plays, the HandleRewardBasedVideoRewarded function should be called but it doesnt. Any help at all is appriciated
I found a Silent Error after debugging in Android Studio, its due to threading issues in Unity.
Solution : Call your handling event in main thread (in Update Method)
bool isAdClosed = false;
bool isRewarded = false;
void Update()
{
if (isAdClosed)
{
if (isRewarded)
{
// do all the actions
// reward the player
isRewarded = false;
}
else
{
// Ad closed but user skipped ads, so no reward
// Ad your action here
}
isAdClosed = false; // to make sure this action will happen only once.
}
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
print("HandleRewardBasedVideoClosed event received");
RequestRewardBasedVideo(); // to load Next Videoad
isAdClosed = true;
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
string type = args.Type;
double amount = args.Amount;
print("HandleRewardBasedVideoRewarded event received for " + amount.ToString() + " " +
type);
isRewarded = true;
}
Vivek's solution worked for me on Unity v20212.1.15f1, although I had to put the code in my GameManager Update function as the AdManager Update function wasn't running when the RewardedAd was shown.