Unity Ads - "IsReady" and "resultcallback" help for Android build

Hi all and @ap-unity - @rasmus-unity - @JeffDUnity3D

I'm aware that with Unity Ads 4.X.X+ things have changes such as Isready and result call back, however, I was really hoping someone can help me with my code. I'm a graphic designer and producer by trade, so coding and even figuring out what might be a 5 minute fix for others, is a weeks worth of time for me. If anyone can please help me with this issue I'm having I would appreciate it. My log shows:

Assets/Scripts/AdsWrapper.cs(25,4): error CS0117: 'ShowOptions' does not contain a definition for 'resultCallback'

Assets/Scripts/AdsWrapper.cs(19,55): error CS0117: 'Advertisement' does not contain a definition for 'IsReady'

I know what lines need to change, but I don't know what to change them to for it to find if the ad is ready and the call back results. Downgrading to 3.7.5 is not an option since Google Play won't accept the SDK advertisement issues from 4.X.X and down.

Any chance someone could please write the lines I could copy and paste? Believe me, I have spent literally the last 2 days googling and trying everything on my own and I simply am not good enough to figure it out. :(

using UnityEngine;
using System.Collections;
using UnityEngine.Advertisements;

public static class AdsWrapper
{

    // we need this layer on top of Advertisement because when the user hits the device home button, Unity
    // calls OnApplicationPause() and then we are supposed to pause the game.  but that also gets called
    // right before an ad is shown, and then we are not supposed to pause the game because the pause menu
    // will be up when the ad completes, which is annoying.  so we need to know before Advertisement.isShowing
    // is true that we are about to show an ad, and then the OnApplicationPause() handler knows not to
    // show the pause menu.
    static bool _isShowing = false;
    public static bool isShowing { get { return _isShowing || Advertisement.isShowing; } }

    public static bool IsReady()
    {
        return Advertisement.isInitialized && Advertisement.IsReady();
    }

    public static void Show(System.Action<ShowResult> callback = null)
    {
        _isShowing = true;
        Advertisement.Show(null, new ShowOptions
        {
            resultCallback = result =>
            {
                _isShowing = false;
                if (callback != null)
                    callback(result);
            }
        });
    }

}

Hi all,

The specific line is:

return Advertisement.isInitialized && Advertisement.IsReady();

and:

resultCallback = result =>

Is there a simple thing to modify those two lines so that I can continue to use this adswrapper script? Ads work fine in my game, this script is so that if a user pauses or leaves the game, the game will pause correctly.

@Ohyouknow

So this compiles and I tried not to change the AdsWrapper class too much, but I can't guarantee it will work for you without know exactly how AdsWrapper was getting called.

I did have to make one change. AdsWrapper.Show() now requires a Placement ID. You can find the appropriate placement ID from your dashboard.

But this should get you started:

using UnityEngine.Advertisements;

public class AdListener : IUnityAdsLoadListener, IUnityAdsShowListener
{
    public bool IsReady = false;

    System.Action<ShowResult> _callback = null;
    string _placementId;

    public AdListener(string placement, System.Action<ShowResult> callback)
    {
        _placementId = placement;
        _callback = callback;
    }

    public void OnUnityAdsAdLoaded(string placementId)
    {
        IsReady = true;
    }

    public void OnUnityAdsFailedToLoad(string placementId, UnityAdsLoadError error, string message)
    {
        IsReady = false;
    }

    public void OnUnityAdsShowStart(string placementId) { }
    public void OnUnityAdsShowClick(string placementId) { }

    public void OnUnityAdsShowComplete(string placementId, UnityAdsShowCompletionState showCompletionState)
    {
        IsReady = false;
        switch (showCompletionState)
        {
            case UnityAdsShowCompletionState.COMPLETED:
                _callback?.Invoke(ShowResult.Finished);
                break;
            case UnityAdsShowCompletionState.SKIPPED:
                _callback?.Invoke(ShowResult.Skipped);
                break;
            case UnityAdsShowCompletionState.UNKNOWN:
                _callback?.Invoke(ShowResult.Failed);
                break;
        }
    }

    public void OnUnityAdsShowFailure(string placementId, UnityAdsShowError error, string message)
    {
        IsReady = false;
    }
}

public static class AdsWrapper
{
    // we need this layer on top of Advertisement because when the user hits the device home button, Unity
    // calls OnApplicationPause() and then we are supposed to pause the game.  but that also gets called
    // right before an ad is shown, and then we are not supposed to pause the game because the pause menu
    // will be up when the ad completes, which is annoying.  so we need to know before Advertisement.isShowing
    // is true that we are about to show an ad, and then the OnApplicationPause() handler knows not to
    // show the pause menu.
    public static bool isShowing { get { return _isShowing || Advertisement.isShowing; } }

    static bool _isShowing = false;
    static AdListener listener = null;

    public static bool IsReady()
    {
        if (!Advertisement.isInitialized) return false;
        if (listener == null) return false;
        if (!listener.IsReady) return false;
        return true;
    }

    public static void Show(string placement, System.Action<ShowResult> callback = null)
    {
        _isShowing = true;
        listener = new AdListener(placement, callback);
        Advertisement.Show(placement, listener);
    }
}

For future projects, our documentation has example scripts that you can drop in without too much modification:
https://docs.unity.com/ads/ImplementingRewardedAdsUnity.html

1 Like

Wow, thank you soooooo much for providing this! It seems to have fixed the adswrapper situation, but it did affect a couple other things, however, those all seem to have the same issue, so if you can please help figure out one of them, I believe it solves it for all.

After dropping the new script in, it affected the scripts which uses the adwrapper (5 IAP’s) which used the “AdsWrapper.Show (result => {” bool.

The 6 errors I’m now getting all say “Cannot convert lambda expression to type ‘string’ because it is not a delegate type”

When I click for a potential fix, it says I can generate a method (which because of my lack of coding skills) I don’t know what that means.

void Ad ()
    {
        YesNoDialog.instance.DestroyWindow = true;
        if (AdsWrapper.IsReady ()) {
            AdsWrapper.Show (result => {
                context.canChangeCharacter = true;
                if (result == ShowResult.Finished) {
                    GMRewrite.freeBonesCount++;
                    GMRewrite.SetScore (GMRewrite.GetScore () + value);
                    boneUnity.currentTime = boneUnity.maxTime;
                    context.UpdateReferences ();
                }
                context.UpdateScore ();
            });
        }
    }
public void ShowHealthAd ()
    {
//        source.PlayOneShot (buttonSound);
        if (AdsWrapper.IsReady ()) {
            AdsWrapper.Show (result => {
                if (result == ShowResult.Finished) {
                    GMRewrite.currentCharacter.Health.currentValue = GMRewrite.currentCharacter.Health.maxValue;
                    Debug.Log ("Health Regen");
                }
            });
        }
    }

    public void ShowStaminaAd ()
    {
//        source.PlayOneShot (buttonSound);
        if (AdsWrapper.IsReady ()) {
            AdsWrapper.Show (result => {
                if (result == ShowResult.Finished) {
                    GMRewrite.currentCharacter.Stamina.currentValue = GMRewrite.currentCharacter.Stamina.maxValue;
                    Debug.Log ("Stamina Regen");
                }
            });
        }
    }
private void WatchAd ()
    {
        YesNoDialog.instance.DestroyWindow = true;
        context.canChangeCharacter = true;
        if (!AdsWrapper.IsReady ()) {
            Debug.LogWarning ("Advertisement is not ready in call to WatchAd().");
            return;
        }
        AdsWrapper.Show (result => {
            if (result == ShowResult.Finished) {
                if (statToRestore == Restore.HEALTH) {
                    GMRewrite.currentCharacter.Health.currentValue = GMRewrite.currentCharacter.Health.maxValue;
                } else if (statToRestore == Restore.TURBO) {
                    GMRewrite.currentCharacter.Stamina.currentValue = GMRewrite.currentCharacter.Stamina.maxValue;
                }
                GMRewrite.SaveGame ();
            }
        });
    }
private void WatchAd ()
    {
        ResumeGame ();
        YesNoDialog.instance.DestroyWindow = true;
        if (!AdsWrapper.IsReady ()) {
            Debug.LogWarning ("Advertisement is not ready in call to WatchAd().");
            return;
        }
        AdsWrapper.Show (result => {
            if (result == ShowResult.Finished) {
                // refill health
                GMRewrite.currentCharacter.Health.currentValue = GMRewrite.currentCharacter.Health.maxValue;
                GMRewrite.SaveGame ();
                StartMission ();
            }
        });
    }
}
if (!context.MissionCompleted && context.MissionType == MissionType.MAINMISSION) {
                if (context.failureCount % 5 == 4) {
                    context.StartCoroutine (SkipLevel ());
                } else if (AdsWrapper.IsReady ()) {
                    AdsWrapper.Show (result => {
                    });
                }
            }
        }

    }

Basically, the issue I believe is (and if you look at the screenshots) “AdsWrapper.Show (result =>” is the hold up. I’m sure now that the new adswrapper script is in, the method in which to show it has to be updated, but I don’t know what to change it to for it to function. If you could please take a look and help with that, I’d appreciate it!

8531090--1138883--Screen Shot 2022-10-21 at 9.57.30 AM.png
8531090--1138886--Screen Shot 2022-10-21 at 9.57.40 AM.png
8531090--1138889--Screen Shot 2022-10-21 at 9.57.50 AM.png
8531090--1138895--Screen Shot 2022-10-21 at 9.58.02 AM.png
8531090--1138907--Screen Shot 2022-10-21 at 9.58.13 AM.png

Hi, so I pressed generate methods for advertisement.show and now the only issue it says it has is for:
if (result == ShowResult.Finished) { and the error is:
CS0019: Operator ‘==’ cannot be applied to operands of type ‘object’ and ‘ShowResult’

If you could help fix this, it would solve it for the other scripts as the error is the same for all 6.

8533397--1139420--Screen Shot 2022-10-22 at 5.27.00 PM.png

Hi @ap-unity any thoughts on what to do next?

hi @ap-unity - Any chance you could please help?

I finally figured it out and it was the easiest and dumbest solution that just happened to skip my mind so much. Thank you @ap-unity

Hello how you solve this i take same erors