Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity Ads - Multiple Buttons gives exponential rewards

Discussion in 'Unity Ads & User Acquisition' started by MadGraph, Jan 4, 2020.

Thread Status:
Not open for further replies.
  1. MadGraph

    MadGraph

    Joined:
    Aug 20, 2019
    Posts:
    4
    Hi everyone,

    I'm really new to C# and Unity
    I've been spending a lot of time trying to debug an issue with Unity Ads and hope someone will be able to help

    I'm building a quizz game showing a Button (WatchAdButton) on each level (one scene by level)
    That button has a rewarded ads script that handles the placement and shows the ad etc... (from Unity's documentation : http://unityads.unity3d.com/help/unity/integration-guide-unity#rewarded-video-ads

    when my Ad is finished, I want to give the player Gems & Load the next level
    Here's my script below

    The issue I have is that
    On Level1 > The script and the button work : they give +5 gems and send the player to the next level

    But on Level 3 > The script seems to be playing 3 times (one for every instance I've created of the button in the past even though the scenes have switched (I thought switching scenes delete the objects from the previous one right?)

    Is there a best practice on Buttons ? Destroying them after rewarding the user?


    Code (CSharp):
    1. #if UNITY_IOS
    2.     private string gameId = "XXXX"; // iOS gameID
    3.     #elif UNITY_ANDROID
    4.     private string gameId = "XXXX"; // Android gameId
    5.     #endif
    6.  
    7.    
    8.     Button myButton;
    9.     private string myPlacementId = "rewardedVideo"; // playing the rewardedVideo placement
    10.  
    11.     // TODO: Change when releasing to production
    12.     bool testMode = true;
    13.    
    14.     void Start()
    15.     {
    16.         myButton = GetComponent<Button> ();
    17.  
    18.         // Set interactivity to be dependent on the Placement’s status:
    19.         myButton.interactable = Advertisement.IsReady (myPlacementId);
    20.  
    21.         // Map the ShowRewardedVideo function to the button’s click listener:
    22.         if (myButton) myButton.onClick.AddListener (ShowRewardedVideo);
    23.  
    24.         // Initialize the Ads listener and service
    25.         Advertisement.AddListener(this);
    26.         Advertisement.Initialize(gameId, testMode);
    27.     }
    28.  
    29.     // Implement a function for showing a rewarded video ad:
    30.     void ShowRewardedVideo () {
    31.         Advertisement.Show (myPlacementId);
    32.     }
    33.  
    34.     // Implement IUnityAdsListener interface methods:
    35.     public void OnUnityAdsReady (string placementId) {
    36.         // If the ready Placement is rewarded, show the ad:
    37.         if (placementId == myPlacementId) {
    38.             myButton.interactable = true;
    39.         }
    40.     }
    41.  
    42.     public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
    43.     {
    44.         // Adding the if RewardedVideo
    45.         if (placementId == myPlacementId)
    46.         {
    47.             // Define conditional logic for each ad completion status:
    48.             if (showResult == ShowResult.Finished)
    49.             {
    50.                 // Reward the user for watching the ad to completion.
    51.                 if (SceneManager.GetActiveScene().buildIndex != 4)
    52.                 {
    53.                     SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
    54.                     PlayFabController.PFC.CompleteLevel(); // Completing Level
    55.                     Destroy(gameObject);
    56.                 }
    57.                 else
    58.                 {
    59.                     Debug.Log("End of the Game");
    60.                     PlayFabController.PFC.EarnGems();
    61.                     Destroy(gameObject);
    62.                 }
    63.             }
    64.             else if (showResult == ShowResult.Skipped)
    65.             {
    66.                 // Do not reward the user for skipping the ad.
    67.                 Debug.Log("Please don't Skip the ad to get your reward!");
    68.             }
    69.             else if (showResult == ShowResult.Failed)
    70.             {
    71.                 Debug.LogWarning("The ad did not finish due to an error.");
    72.             }
    73.         }
    74.         else
    75.         {
    76.             Debug.Log("Hacking is bad!");
    77.         }
    78.  
    79.     }
    80.  
    81.     public void OnUnityAdsDidError (string message) {
    82.         // Log the error.
    83.         Debug.LogWarning ("An error occured.");
    84.     }
    85.  
    86.     public void OnUnityAdsDidStart (string placementId) {
    87.         // Optional actions to take when the end-users triggers an ad.
    88.         Debug.Log("Launched The Ad from Level.");
    89.     }
    90. }
    EDIT : I've added "Destroy(gameObject);" after the Reward is completed

    Not sure if it's a good thing to do that though
     
    leandrovtd likes this.
  2. MadGraph

    MadGraph

    Joined:
    Aug 20, 2019
    Posts:
    4
    EDIT : It seems that it loops multiple times within the OnUnityAdsDidFinish()

    now with the Destroy, the console logs

    Code (Boo):
    1. MissingReferenceException: The object of type 'RewardedAdsButton' has been destroyed but you are still trying to access it.
    2. Your script should either check if it is null or you should not destroy the object.
    Meaning that after destroying it, it tries to run the function one more time, No idea why that happens

    Thx for helping
    M.
     
  3. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    My guess here is that each time your script runs in a new level the Start Method is getting invoked which on line 25 is adding a listener. These listeners are probably never getting removed so when level 2 starts, you now have 2 listeners that get called, and on level 3 you have 3 listeners get called which means your reward method gets called 3 times. You can either remove the listener at the end of the level, or stop adding the listener over and over at level start and just do it the one time.
     
    MadGraph likes this.
  4. MadGraph

    MadGraph

    Joined:
    Aug 20, 2019
    Posts:
    4
    You're a rockstar !! Thanks a lot <3

    > I was focusing on the gameobject

    Should I just Add a reference saying that if there are other AddListeners, destroy them, else use only that one (Singleton I guess?)

    Thanks a lot
     
  5. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    You could tap into the destroy method on the gameobject and call Advertisments.RemoveListener(this); when you tear down this gameobject.

    You could also move this script over to an object that doesn't get destroyed and re-created between scene loads and so is just always in the background ready to show ads and only gets init and listener added once. Fyi you will want to look into GameObject.DontDestroyOnLoad for this.
     
    bakablog2000, leandrovtd and MadGraph like this.
  6. MadGraph

    MadGraph

    Joined:
    Aug 20, 2019
    Posts:
    4
    Thanks a lot @sbankhead!! that was driving me crazy! Problem solved by removing the Listener after completion with Advertisement.RemoveListener(this);
     
    leandrovtd likes this.
Thread Status:
Not open for further replies.