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 video ad works fine until scene is reloaded

Discussion in 'Unity Ads & User Acquisition' started by AdXxRi123, Jan 6, 2020.

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

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    Hello everyone! I have a game that when you lose 3 lives a lose panel appears and it gives you 3 options, Continue button, this will resume your progress (you need to watch the ad) Restart Level button (it reloads the scene) and Back to menu button. When I enter for the first time to the game the continue button displays the ad and resumes the game properly but If then lose again and click the restart button the ad will not work the next time.

    An error in console appears that the object is DESTROYED. Please im having such a headache trying to solve this, any solution? Im using Advertisement Package Manager version 3.4.1
     
  2. rasmus-unity

    rasmus-unity

    Moderator

    Joined:
    Aug 15, 2014
    Posts:
    1,312
    Hi,

    Thanks for reporting. Do you get any errors, e.g. in devicelog?

    /Rasmus
     
  3. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    Yes, these errors appear :
    MissingReferenceException: The object of type 'ContinueAdButton' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.

    and the object is not destroyed and the references are all correct, I mean it works at the first time.
     
  4. rasmus-unity

    rasmus-unity

    Moderator

    Joined:
    Aug 15, 2014
    Posts:
    1,312
    Thanks again. Happens in editor only and/or also device? (Sorry, not on SDK team, just trying to collect info for us to reproduce it easier)
     
  5. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    Both, editor and device
     
  6. nunorbrito18

    nunorbrito18

    Joined:
    Dec 14, 2019
    Posts:
    12
    When you load a new scene on the first time you have an object called Placeholder and after the scene load, you don't have... For me, update [Window -> Package Manager -> Advertisement to 3.4.1] seems to fix it.
     
  7. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    Hello! Thanks for your reply, I updated it and stills gives me the error, any other solution? :(
     
  8. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    MissingReferenceException: The object of type 'ContinueAdButton' has been destroyed

    ContinueAdButton is from your game, not from our sdk. We have no control over you destroying objects. If you load a new scene depending on how it is loaded, the existing scene is thrown away along with all objects in the scene. This seems like what is happening, but without any repro script/project, no stacktrace error, or anything else its hard for us to troubleshoot this issue.
     
  9. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19

    This is mi continue ad button code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.Advertisements;
    6.  
    7. public class ContinueAdButton : MonoBehaviour, IUnityAdsListener
    8. {
    9.     //string gameId = "3328561";
    10.     string myPlacementId = "rewardedVideo";
    11.     Button continueButton;
    12.  
    13.     [Header("Sounds")]
    14.     public AudioSource buttonClick;
    15.  
    16.     [Header("Referencia de scripts")]
    17.     [SerializeField] private BallManager[] ballManagerScript; // Referencias a los scripts de las bolas.
    18.     [SerializeField] private ScaleTweenLoseGame scaleTweenLoseScript;
    19.  
    20.     void Start()
    21.     {
    22.         continueButton = GetComponent<Button>();
    23.  
    24.         // Set interactivity to be dependent on the Placement’s status:
    25.         continueButton.interactable = Advertisement.IsReady(myPlacementId);
    26.  
    27.         // Map the ShowRewardedVideo function to the button’s click listener:
    28.         if (continueButton)
    29.         {
    30.             continueButton.onClick.AddListener(ShowRewardedVideo);
    31.         }
    32.             // Initialize the Ads listener and service:
    33.             Advertisement.AddListener(this);
    34.             //Advertisement.Initialize(gameId, true);
    35.     }
    36.  
    37.     // Implement a function for showing a rewarded video ad:
    38.     void ShowRewardedVideo()
    39.     {
    40.         buttonClick.Play();
    41.         Advertisement.Show(myPlacementId);
    42.         continueButton.onClick.RemoveAllListeners();
    43.     }
    44.  
    45.     #region Rewarded Ads Methods
    46.  
    47.     // Implement IUnityAdsListener interface methods:
    48.     public void OnUnityAdsReady(string placementId)
    49.     {
    50.         // If the ready Placement is rewarded, activate the button:
    51.         if (placementId == myPlacementId)
    52.         {
    53.             continueButton.interactable = true;
    54.         }
    55.     }
    56.  
    57.     public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
    58.     {
    59.         // Define conditional logic for each ad completion status:
    60.         if (showResult == ShowResult.Finished)
    61.         {
    62.             AdSeen();
    63.         }
    64.         else if (showResult == ShowResult.Skipped)
    65.         {
    66.             // Do not reward the user for skipping the ad.
    67.         }
    68.         else if (showResult == ShowResult.Failed)
    69.         {
    70.             Debug.LogWarning("The ad did not finish due to an error.");
    71.         }
    72.     }
    73.  
    74.     public void OnUnityAdsDidError(string message)
    75.     {
    76.         // Log the error.
    77.     }
    78.  
    79.     public void OnUnityAdsDidStart(string placementId)
    80.     {
    81.      
    82.     }
    83.  
    84.     public void AdSeen()
    85.     {
    86.         // Reward the user for watching the ad to completion.
    87.         Time.timeScale = 1;
    88.         GameManager.instance.lifes = 3;
    89.         GameManager.instance.startingTime = 3f;
    90.         scaleTweenLoseScript.OnClose();
    91.         GameManager.instance.startCounter.Play();
    92.         GameManager.instance.StartingGame();
    93.  
    94.         for (int i = 0; i < ballManagerScript.Length; i++)
    95.         {
    96.             ballManagerScript[i].ActBallFall();
    97.         }
    98.     }
    99.  
    100.     #endregion
    101. }
    I initialize the sdk in another script to only initialize once.

    For reloading the scene I use

    Code (CSharp):
    1. SceneManager.LoadScene("Game");
    The button works the first time but when I reload the game the ad shows but the ShowResult == Finished doesnt work.

    How can I solve this?
     
  10. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    Looking at just your script, the script itself seems fine. ContinueAdButton is what is getting nulled out after scene reload. There should be a gameobject that this script is attached to. Does that gameobject exist in the scene your loading with this script attached to it? My guess is this script is attached to something in a main menu scene, and you load your game scene which does not have this object. You then try to access a reference to that object which is null.

    Some things to try:
    1) In the Game scene where the reference is broken, have you tried refreshing the reference to the gameobject holding the ContinueAdButton script. Something like GameObject.Find("GameObjectHoldingContinueAdButtonScript") and then calling GetComponent<ContinueAdButton>() on that gameObject to refresh the reference in the new scene?

    2) Try adding a DontDestoryOnLoad(GameObjectHoldingContinueAdButtonScript); to the ContinueAdButton start method so this object doesn't get deleted on scene load. make sure you account for this logic change in your game so that you dont have multiple copies of the script getting created as that will create new problems for you.
     
    willcottrell and ToroidGames like this.
  11. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    The gameobject is only on the game scene, because it is only used there. I tried the DontDestroyOnLoad but it stil gave me error. I will try the first thing you said see if it works.

    I think the error is on the advertising part, because I got all the code that needs to be done after the ad is played and put it on an appart method to see if it worked and it worked all the time, on the first time and on reloading. But when I implement it as seen above it just works the first time.
     
  12. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    Can you provide the full stracktrace to the MissingReferenceException so I can a little better what the code path that leads to the exception is.
     
  13. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.GameObject.GetComponent[T] () (at C:/buildslave/unity/build/Runtime/Export/Scripting/GameObject.bindings.cs:28)
    ScaleTweenLoseGame.OnClose () (at Assets/Scripts/Menu/TweenAnimations/ScaleTweenLoseGame.cs:41)
    ContinueAdButton.AdSeen () (at Assets/Scripts/Ads/ContinueAdButton.cs:92)
    ContinueAdButton.OnUnityAdsDidFinish (System.String placementId, UnityEngine.Advertisements.ShowResult showResult) (at Assets/Scripts/Ads/ContinueAdButton.cs:64)
    UnityEngine.Advertisements.Platform.Platform+<>c__DisplayClass41_0.<UnityAdsDidFinish>b__0 () (at Library/PackageCache/com.unity.ads@3.4.1/Runtime/Advertisement/Platform/Platform.cs:171)
    UnityEngine.Advertisements.Utilities.CoroutineExecutor.Update () (at Library/PackageCache/com.unity.ads@3.4.1/Runtime/Advertisement/Utilities/CoroutineExecutor.cs:17)
     
  14. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    So on line 92 of your script you call GameManager.instance.StartingGame(); which in turn invokes some sort of tween library that is trying to call getComponent on a gameobject that is null. Open up ScaleTweenLoseGame look at line 41 and right before do a gameObject.Find("gameObjectNameHere") for the gameobject you are trying to call getComponent on. Whatever that object is, its null and its not controlled by our ads sdk.

    Given that the tween library has some script ScaleTweenLoseGame and this is called from a StartingGame method, im thinking some cleanup logic is happening the same time some start game logic is happening and its causing an issue. It seems odd to me that a script named ScaleTweenLoseGame is happening in your StartingGame logic? Might just be poor naming.
     
  15. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    ScaleTweenLoseGame is only called once when the panel where the continue button, the retry button and the menu button are located. is in an OnEnable so a nice tweening animation is made. I tried taking the script off and just activating and desactivating the canvas and the error goes to another place. So the ScaleTweenLoseGame is not the problem
     
  16. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19

    Code (CSharp):
    1.   scaleTweenLoseScript.OnClose();
    2.  
    This only calls a method that does the closing tweening animation
     
  17. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    Please review your stacktrace as it shows that your exception is from:
    this is not our code and we have no control over what is happening in this script.

    To help you understand this better, try commenting out the logic in the method AdSeen and replace it with a debug.Log statement that says "Ad Shown". Your error should go away and at that point you can start adding back in logic until it breaks again at which point that should help you identify where your code is busted.
     
  18. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    In your StartingGame method do you load the scene at that point? Do you make sure to stop the tweening animation before you do so? If not, your tweening library is going to be trying to animate an object in the scene thats being torn down by the SceneLoader as it opens the new scene. Scene loading does not make sure your scripts have stopped executing before deleting objects, thats your responsibility.
     
  19. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    What you said here is pretty interesting, let me check if all the tweening is done before reloading, I will post a reply after testing.
     
  20. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19

    I just tested and the tweening is completely done before realoading the scene. I will try and re-explain my problem more detailed to see if it helps.

    You are playing the game, you lose, and when you lose this "lost panel" appears with its tweening. The lost panel has 3 buttons, continue button (you watch an ad, an then you can resume your game where you died WITHOUT RELOADING SCENE), retry (does a SceneManager.LoadScene("Game"); to start the game from 0) and menu, which is loading the menu scene.

    So you lose and click the continue button, you see the ad, your game gets resumed, and everything is working fine. What is the problem? That if you click on the retry button (this button only loads again the scene, nothing else) when you die and click on the continue button, that error appears.

    Why does it work on the first time and it doesnt work when yo reload the scene?

    The game scene is loaded because you click the "play" button on the menu so there are not loading problems at the beggning.

    Things I tried:

    1) I tried DonDestroyOnLoad and it didnt work.

    2) I deleted the tweening script and only abled and disabled the panel, then the error showed up in another object, the message was the same, that it was being destroyed.

    3) I tried putting asigning my AdSeen(); method to the continue button WITHOUT any ad thing. And it worked at the first time and when reloading scene.

    So, why when I put the method alone without any ads showing it works all the time and with the ads it only works on the first time?

    I think maybe I am doing something wrong with the ads, I PLEASE need help for this, I have been 2 weeks struggling with this error.

    Extra info:
    1) If you click the "menu" button on the "lost panel" and click the "play" button, is like clicking the retry button, the continue button will not work. It only works the FIRST time it is loaded.

    2) Continue button and lost panel are disabled when the scene starts, they only enable when player dies.

    3) Continue button DOES NOT DO any scene loading.

    4) When click on the retry button, the tweening is done completely AND THEN the scene is loaded.
     
  21. Geri860

    Geri860

    Joined:
    Aug 25, 2018
    Posts:
    5
    Hi there :)
    I'm having the exact problem. First adshow work, after scene reload it gives me this error too. It says the object is destroyed but in reality its not. Pls update me if you find any kind of solution.
     
  22. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    Hello! No.. I dind´t find any solution yet. Im having such a headache trying to solve this. Unity Technologies didnt responde anymore.. If you find any solution please tell me.
     
  23. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    If you are willing to share your project with us that reproduces the issue we can take a look for you. Without any way to reproduce the issue in a standalone project its very hard for us to help you. If you would like to do this, please open a support ticket where you can upload your project and we will use the repro steps above to take a look at it.
     
  24. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19
    How Do I open a support ticket to share the project?
     
  25. SpeedyDev

    SpeedyDev

    Joined:
    Jun 18, 2017
    Posts:
    2
    I had the same problem too! It is happens because the listener
    Code (CSharp):
    1. Advertisement.AddListener(this);
    is not removed when the scene is reloaded. So when you reload the scene the second time, you have 2 listeners active. The old listener from the previous scene gets called once the ad is done, but it references objects from the old scene.

    Anyway to solve it, just add Advertisement.RemoveListener(this) before you reload the scene.
     
  26. AdXxRi123

    AdXxRi123

    Joined:
    Nov 8, 2018
    Posts:
    19

    It worked!!! Thank you mate! I have been weeks trying to solve this... You are a hero <3
     
    wrmmrw likes this.
  27. LukiPupsiii

    LukiPupsiii

    Joined:
    Jun 14, 2019
    Posts:
    1

    OMG, I had that problem for so long, you finally solved it!! Unity should definitely add that to their Ad manual. Thank you so much for sharing that with us!
     
  28. Udit_Warikoo

    Udit_Warikoo

    Joined:
    Sep 4, 2017
    Posts:
    5
    Hi, I'm new to this. Could u tell me where I'm supposed to add The remove Listener component ? Is it before the add listener line ?
     
  29. rasmus-unity

    rasmus-unity

    Moderator

    Joined:
    Aug 15, 2014
    Posts:
    1,312
    @Udit_Warikoo, you should call Advertisement.RemoveListener(this) when you reload the scene. If you can share the code where you reload scene, it will likely be easier to show.

    /Rasmus
     
  30. Udit_Warikoo

    Udit_Warikoo

    Joined:
    Sep 4, 2017
    Posts:
    5
    Do i need to reload the scene in my script containing the onAdFInished method ?
     
  31. rasmus-unity

    rasmus-unity

    Moderator

    Joined:
    Aug 15, 2014
    Posts:
    1,312
    At what point are you reloading the scene? When restarting game, e.g. after game over?
     
  32. Udit_Warikoo

    Udit_Warikoo

    Joined:
    Sep 4, 2017
    Posts:
    5
    I have a button that rewards extra gems on the main menu scene after watching the ad.

    I also use another GameObject called Gem Manager in which i update the value of the gems and display them on the home screen. It is in this object that i reload the scene. Is there a way to call removeListener() in another gameobject. if yes, then what should i pass as its parameter because using Advertisements.RemoveListener(this) throws an error

    EDIT:
    I figured it out. I used the following function in my script and now it works like a charm!!

    public void OnDestroy()
    {
    Advertisement.RemoveListener(this)'
    }
     
    Last edited: Jul 14, 2020
    rasmus-unity likes this.
  33. quintonleongnam

    quintonleongnam

    Joined:
    May 9, 2018
    Posts:
    9
    @SpeedyDev Thank you so much for that! you're a legend! and thanks @Udit_Warikoo
    I also added

    public void OnDestroy()
    {
    Advertisement.RemoveListener(this);
    }

    to the RewardedAdButton Script in my game and it worked like a charm!
    Thank you all!
     
    Last edited: Aug 26, 2020
    DEPREDA likes this.
  34. kocakberatfurkan

    kocakberatfurkan

    Joined:
    Sep 14, 2019
    Posts:
    5
    Hello, is this function no longer in use? I can't implement RemoveListener
     
  35. quintonleongnam

    quintonleongnam

    Joined:
    May 9, 2018
    Posts:
    9
    @kocakberatfurkan I'm looking at your code that you shared above and it seems there are a few typos which might be preventing your code from working.
    instead of
    public void OnDestroy()
    {
    Advertisement.RemoveListener(this)'
    }

    you need to type:

    public void OnDestroy()
    {
    Advertisement.RemoveListener(this);
    }

    the line of code needs to be further tabbed in and you need to initialize the code by putting a ; at the end.

    p.s sincere apologies I had a typo in my previous post that didn't have a ; at the end. I have since rectified this.
     
  36. kocakberatfurkan

    kocakberatfurkan

    Joined:
    Sep 14, 2019
    Posts:
    5
    Thanks for replying, I realized that typo but my problem is, I do not have a RemoveListener function after I do Advertisement. , I am asking if this function changed its name or I am missing some library implementation ?
     
  37. kocakberatfurkan

    kocakberatfurkan

    Joined:
    Sep 14, 2019
    Posts:
    5
    Oh I realized that I am using Admob ads, so it might be related to this. But I have the same problem, does anybody know a similar function for me to use ?
     
  38. svlewis

    svlewis

    Joined:
    Oct 1, 2018
    Posts:
    3
    I have only commented on this website once before, I came to say thank you for this simple but so hard to freaking find fix! I hadn't needed to remove a listener before!
     
  39. FatemaD

    FatemaD

    Joined:
    Apr 22, 2020
    Posts:
    1
    Hi, Did you find a solution since I am also I’m using admob and facing similar issue
     
  40. sbankhead

    sbankhead

    Unity Technologies

    Joined:
    Jul 27, 2014
    Posts:
    97
    Please do not re-open old threads. If your having an issue open up a new request with details specific to your case.
     
Thread Status:
Not open for further replies.