Search Unity

Question Mediation rewarded ad cancelled scenario

Discussion in 'Unity Mediation' started by Delcasda, Nov 14, 2021.

  1. Delcasda

    Delcasda

    Joined:
    Mar 3, 2013
    Posts:
    27
    Hi, I am trying to test the scenario where the user don't finish watching the rewarded ad as I would like to give regular coins rather than bonus coins on that case. So I was using on Ad Close event but looks like that event is always fired even if the ad is watched to the end so the coins are being assigned twice bonus+regular. On the editor the reward ad shows a forward button and a close button after it , on mobile there is no way to cancel the test ad so how can this be tested or should I assume all the rewarded ads from all sources are going to be unskippable ?
     
    Novack likes this.
  2. MonishGupta

    MonishGupta

    Unity Technologies

    Joined:
    May 30, 2018
    Posts:
    9
    Hey Delcasda!

    So if I'm understanding correctly you'd like to reward users for watching an ad with coins, but award bonus coins if they finish the ad? Are these coins part of one currency or are regular coins and bonus coins separate currencies?

    If bonus and regular coins are part of the same currency you can award coins on the AdClosed event and use the ImpressionEventPublisher.OnImpression to award bonus coins as this event is fired when an ad network determines if an ad is witnessed in its entirety.

    If bonus and regular coins are part of separate currencies and are looking to award either regular or bonus coins. After showing an ad, wait for about a minute before rewarding a user. If you receive only an AdClosed event, then after the minute elapses award the user only regular coins. If you receive both AdClosed and ImpressionEventPublisher.OnImpression then immediately reward the user only bonus coins.

    In summary AdClosed is fired whenever an ad is closed regardless if it was fully witnessed. ImpressionEventPublisher.OnImpression is fired when an ad is deemed fully witnessed. So you would need to wait the full duration of an ad before determining if the user watched a portion or all of the ad.

    Let us know if you have any more questions!
     
  3. Delcasda

    Delcasda

    Joined:
    Mar 3, 2013
    Posts:
    27
  4. MonishGupta

    MonishGupta

    Unity Technologies

    Joined:
    May 30, 2018
    Posts:
    9
    Hey @Delcasda ! Excuse what I said about OnImpression as it fires as soon as an ad shows, which won't help your situation. If you're using exclusively using Rewarded Ads OnUserRewarded is the way to go.

    I've went ahead and implemented a Monobehavior wrapper on a Rewarded Ad that should allow you to determine if a Rewarded Ad has been partially or fully watched. Just attach RewardedFullOrPartialWatch.cs on a GameObject providing your rewarded ad unit, game id, and subscribe to OnPartialWatch or OnFullWatch as needed. I've attached a modified version of our samples as a .unitypackage for your reference that you can check out.

    RewardedFullOrPartialWatch.cs:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using Unity.Services.Core;
    4. using Unity.Services.Mediation;
    5. using UnityEngine;
    6. using UnityEngine.Events;
    7.  
    8. public class RewardedFullOrPartialWatch : MonoBehaviour
    9. {
    10.     IRewardedAd ad;
    11.     public string adUnitId = "rewarded_all_adunit";
    12.     public string gameId = "3804049";
    13.  
    14.     public UnityEvent OnPartialWatch;
    15.     public UnityEvent OnFullWatch;
    16.  
    17.     // Time after OnAdClosed or OnUserRewarded to expect an OnAdClosed or OnUserRewarded. When elapsed fire partial or full watch event.
    18.     private float callbackTimeLeverage = 1f;
    19.  
    20.     private bool adClosedRecieved = false;
    21.     private bool adUserRewardedRecieved = false;
    22.  
    23.     private bool waiting = false;
    24.  
    25.     public async void Start()
    26.     {
    27.         try
    28.         {
    29.             InitializationOptions initializationOptions = new InitializationOptions();
    30.             initializationOptions.SetGameId(gameId);
    31.             await UnityServices.InitializeAsync(initializationOptions);
    32.  
    33.             InitializationComplete();
    34.         }
    35.         catch (Exception e)
    36.         {
    37.             InitializationFailed(e);
    38.         }
    39.     }
    40.  
    41.     public void SetupAd()
    42.     {
    43.         //Create
    44.         ad = MediationService.Instance.CreateRewardedAd(adUnitId);
    45.  
    46.         //Subscribe to events
    47.         ad.OnLoaded += AdLoaded;
    48.         ad.OnFailedLoad += AdFailedLoad;
    49.  
    50.         ad.OnShowed += AdShown;
    51.         ad.OnFailedShow += AdFailedShow;
    52.         ad.OnClosed += AdClosed;
    53.         ad.OnUserRewarded += UserRewarded;
    54.     }
    55.  
    56.     public void ShowAd()
    57.     {
    58.         if (ad.AdState == AdState.Loaded)
    59.         {
    60.             ad.Show();
    61.         }
    62.     }
    63.  
    64.     void InitializationComplete()
    65.     {
    66.         SetupAd();
    67.         ad.Load();
    68.     }
    69.  
    70.     void InitializationFailed(Exception e)
    71.     {
    72.         Debug.Log("Initialization Failed: " + e.Message);
    73.     }
    74.  
    75.     void AdLoaded(object sender, EventArgs args)
    76.     {
    77.         Debug.Log("Ad loaded");
    78.     }
    79.  
    80.     void AdFailedLoad(object sender, LoadErrorEventArgs args)
    81.     {
    82.         Debug.Log("Failed to load ad");
    83.         Debug.Log(args.Message);
    84.     }
    85.  
    86.     void AdShown(object sender, EventArgs args)
    87.     {
    88.         //pre-load the next ad
    89.         ad.Load();
    90.         Debug.Log("Ad shown!");
    91.     }
    92.  
    93.     void AdClosed(object sender, EventArgs e)
    94.     {
    95.         Debug.Log("Ad has closed");
    96.         // Execute logic after an ad has been closed.
    97.         adClosedRecieved = true;
    98.         if (!waiting)
    99.         {
    100.             StartCoroutine(WaitForOtherCallback());
    101.         }
    102.     }
    103.  
    104.     void AdFailedShow(object sender, ShowErrorEventArgs args)
    105.     {
    106.         Debug.Log(args.Message);
    107.     }
    108.  
    109.     void UserRewarded(object sender, RewardEventArgs e)
    110.     {
    111.         Debug.Log($"Received reward: type:{e.Type}; amount:{e.Amount}");
    112.         adUserRewardedRecieved = true;
    113.         if (!waiting)
    114.         {
    115.             StartCoroutine(WaitForOtherCallback());
    116.         }
    117.     }
    118.  
    119.     IEnumerator WaitForOtherCallback()
    120.     {
    121.         yield return new WaitForSeconds(callbackTimeLeverage);
    122.         if (adClosedRecieved && adUserRewardedRecieved)
    123.         {
    124.             OnFullWatch.Invoke();
    125.         }
    126.         else if (adClosedRecieved)
    127.         {
    128.             OnPartialWatch.Invoke();
    129.         }
    130.  
    131.         adClosedRecieved = false;
    132.         adUserRewardedRecieved = false;
    133.     }
    134.  
    135.     public void ConsoleLog(string message)
    136.     {
    137.         Debug.Log(message);
    138.     }
    139. }
    140.  


    Let me know if you can't get this working or have any questions about the solution. Thanks for your patience, hope this helps!
     

    Attached Files:

    skfldao and Novack like this.
  5. skfldao

    skfldao

    Joined:
    Jul 28, 2019
    Posts:
    18
    Hello!
    Found this thread while editing the reward receiving section of rewarded ads.
    In RewardedFullOrPartialWatch.cs, I couldn't find the part where the wait variable was changed.
    In what cases does it change to True?
     
  6. jcGrenier

    jcGrenier

    Unity Technologies

    Joined:
    Feb 23, 2021
    Posts:
    145
    I assume this was a mistake in the snippet, and waiting should be set to true in WaitForOtherCallback
     
    skfldao likes this.