IronSource rewarded ad sometimes make the variable from my script null

Sorry if the catergory of this post is not correct, it should be IronSource but I just couldn’t find it.

About my question, every time I want to watch a rewarded ad from my game, there is a small chance that all the variables in my script becomes null, and break my game, please take a look at my script:

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

public class LoadRewarded : MonoBehaviour
{
    public LanguageManager languageManager;

    public Button backButton;
    public Button coinButton;
    public Button diamondButton;
    public GameObject[] loadingButtons;

    public ConfirmMenu confirmMenu;
    public ShopManager shopManager;

    public Animator darkBg;

    [SerializeField] private int diamondToAdd;
    [SerializeField] private int coinToAdd;

    private bool adForCoins;
    private bool adForDiamonds;

    public GameObject noWifiPanel;

    void OnEnable()
    {
        //Add AdInfo Rewarded Video Events
        IronSourceRewardedVideoEvents.onAdOpenedEvent += RewardedVideoOnAdOpenedEvent;
        IronSourceRewardedVideoEvents.onAdClosedEvent += RewardedVideoOnAdClosedEvent;
        IronSourceRewardedVideoEvents.onAdAvailableEvent += RewardedVideoOnAdAvailable;
        IronSourceRewardedVideoEvents.onAdUnavailableEvent += RewardedVideoOnAdUnavailable;
        IronSourceRewardedVideoEvents.onAdShowFailedEvent += RewardedVideoOnAdShowFailedEvent;
        IronSourceRewardedVideoEvents.onAdRewardedEvent += RewardedVideoOnAdRewardedEvent;
        IronSourceRewardedVideoEvents.onAdClickedEvent += RewardedVideoOnAdClickedEvent;

        // Start polling for ad availability every second
        StartCoroutine(CheckAndLoadAdCoroutine());
    }

    /************* RewardedVideo AdInfo Delegates *************/
    // Indicates that there’s an available ad.
    // The adInfo object includes information about the ad that was loaded successfully
    // This replaces the RewardedVideoAvailabilityChangedEvent(true) event
    void RewardedVideoOnAdAvailable(IronSourceAdInfo adInfo) {
    }
    // Indicates that no ads are available to be displayed
    // This replaces the RewardedVideoAvailabilityChangedEvent(false) event
    void RewardedVideoOnAdUnavailable() {
    }
    // The Rewarded Video ad view has opened. Your activity will loose focus.
    void RewardedVideoOnAdOpenedEvent(IronSourceAdInfo adInfo){
    }
    // The Rewarded Video ad view is about to be closed. Your activity will regain its focus.
    void RewardedVideoOnAdClosedEvent(IronSourceAdInfo adInfo)
    {
        ActivateButton();
    }
    // The user completed to watch the video, and should be rewarded.
    // The placement parameter will include the reward data.
    // When using server-to-server callbacks, you may ignore this event and wait for the ironSource server callback.
    void RewardedVideoOnAdRewardedEvent(IronSourcePlacement placement, IronSourceAdInfo adInfo)
    {
        ActivateButton();

        string[] lines = languageManager.textsForConfirmMenu[languageManager.languageId].text.Split('\n');

        if(adForCoins)
        {
            shopManager.coins += coinToAdd;
            shopManager.SavePlayerMoney();

            confirmMenu.SetText(lines[2]);
        }
        else if(adForDiamonds)
        {
            shopManager.diamonds += diamondToAdd;
            shopManager.SavePlayerMoney();

            confirmMenu.SetText(lines[3]);
        }

        confirmMenu.ShowOkButton();
        confirmMenu.SetMeActive();
    }
    // The rewarded video ad was failed to show.
    void RewardedVideoOnAdShowFailedEvent(IronSourceError error, IronSourceAdInfo adInfo){
        string[] lines = languageManager.textsForConfirmMenu[languageManager.languageId].text.Split('\n');
    
        confirmMenu.SetText(lines[5]);
        confirmMenu.ShowOkButton();
        confirmMenu.SetMeActive();

        ActivateButton();
    }
    // Invoked when the video ad was clicked.
    // This callback is not supported by all networks, and we recommend using it only if
    // it’s supported by all networks you included in your build.
    void RewardedVideoOnAdClickedEvent(IronSourcePlacement placement, IronSourceAdInfo adInfo){   
    }

    void Update()
    {
        CheckInternetAndUpdateUI();
    }

    private void CheckInternetAndUpdateUI()
    {
        if(IronSource.Agent.isRewardedVideoAvailable()) //There is an ad loaded
        {
            noWifiPanel.SetActive(false);
            coinButton.gameObject.SetActive(true);
            diamondButton.gameObject.SetActive(true);

            foreach(GameObject loadingButton in loadingButtons)
            {
                loadingButton.SetActive(false);
            }
        }
        else if(Application.internetReachability != NetworkReachability.NotReachable) // Waiting to load the ad
        {
            noWifiPanel.SetActive(false);
            coinButton.gameObject.SetActive(false);
            diamondButton.gameObject.SetActive(false);

            foreach(GameObject loadingButton in loadingButtons)
            {
                loadingButton.SetActive(true);
            }
        }
        else // No internet
        {
            noWifiPanel.SetActive(true);
            coinButton.gameObject.SetActive(false);
            diamondButton.gameObject.SetActive(false);
            
            foreach(GameObject loadingButton in loadingButtons)
            {
                loadingButton.SetActive(true);
            }
        }
    }

    private void DesactivateButton()
    {
        darkBg.SetTrigger("LoadAd");

        backButton.interactable = false;
        coinButton.interactable = false;
        diamondButton.interactable = false;
    }

    private void ActivateButton()
    {
        if (languageManager == null)
        {
            Debug.LogError("language manager is null");
        }
        if (confirmMenu == null)
        {
            Debug.LogError("confirmMenu is null");
        }
        if (shopManager == null)
        {
            Debug.LogError("Shop manager is null.");
        }
        if (darkBg == null)
        {
            Debug.LogError("darkBg is null");
        }
        if (noWifiPanel == null)
        {
            Debug.LogError("noWifiPanel is null");
        }

        StartCoroutine(DelayedActivateButtons());
    }

    private IEnumerator DelayedActivateButtons()
    {
        yield return null; // Wait for 1 frame

        darkBg.SetTrigger("AdDone");

        backButton.interactable = true;
        coinButton.interactable = true;
        diamondButton.interactable = true;

        Debug.Log("Buttons activated after scene load.");
    }

    public void WatchAdForCoins()
    {
        DesactivateButton();
        adForCoins = true;
        adForDiamonds = false;
        LoadAd();
    }

    public void WatchAdForDiamonds()
    {
        DesactivateButton();
        adForCoins = false;
        adForDiamonds = true;
        LoadAd();
    }

    public void LoadAd()
    {
        Debug.Log("showing rewarded ad");
        IronSource.Agent.showRewardedVideo();
    }

    void ShowAd()
    {
        IronSource.Agent.showRewardedVideo();
    }

    private IEnumerator CheckAndLoadAdCoroutine()
    {
        while (true)  // Run forever (or until you stop it)
        {
            if (!IronSource.Agent.isRewardedVideoAvailable()) // Check if ad is available
            {
                Debug.Log("Ad not available, trying to load...");
                IronSource.Agent.loadRewardedVideo();  // Try to load an ad if it's not available
            }

            yield return new WaitForSeconds(3);  // Wait for 1 second before checking again
        }
    }
}

I would say that this bug happens one time every 30 ads and I cannot find why, my theory is that when the game is showing the ad, unity pauses itself which results in it forgeting some variable, it might be stupid but this is what I think is happening!

Anyway thank you very much for taking the time to read my problem! Have a great day!

IronSource cannot reach into your private classes and make things null. That’s not a thing. You just have some other bug, perhaps because IronSource is doing something your code does not anticipate.

Your job is to find out why and what is happening.

The answer is always the same… ALWAYS!

How to fix a NullReferenceException error

Three steps to success:

  • Identify what is null ← any other action taken before this step is WASTED TIME
  • Identify why it is null
  • Fix that

NullReference is the single most common error while programming. Fixing it is always the same.

Some notes on how to fix a NullReferenceException error in Unity3D:

http://plbm.com/?p=221

1 Like

Please only use the 2D tag when you’re discussing 2D features because when you do, it puts it into the 2D product area.

I’ll remove that tag.

Thanks.

Thank you very much for your answer (and also sorry for the 2D tag), I found out that it was indeed because of the game pausing while showing the ad that the variables where null, and you have to wait for the game to unpause again! So basically the solution was to simply make a coroutine that waits for the game to resume! Hope it can help people who got the same problem, and thank you again for hinting me the solution!

1 Like