IUnityAdsInitializationListener freezes unity when is not monobehavior

Hello,

I am using the advertisement package of unity version 4.0.0 and I have followed the instructions from here Initializing the SDK in Unity

The only difference from the documentation is that I am using the interface IUnityAdsInitializationListener on a non mono behaviour class and as part of a promise chain that is responsible to initialise my game.

As soon as the initialisation happens, it just freaks out. Why is that happening? why do I need to use Monobehaviour for something that doesn’t need it? Doesn’t cancel the purpose to pass the interface as an argument if there are under the hood dependencies?

public class AdsInitializeTask : IUnityAdsInitializationListener
    {
        private readonly IPromise promise;

        public AdsInitializeTask()
        {
            promise = new Promise();
        }
       
        public IPromise Initialize(string gameId,bool testMode)
        {
            Advertisement.Initialize(gameId, testMode,this);
           
            return promise;
        }
       
        public void OnInitializationComplete()
        {
            promise.Dispatch();
        }

        public void OnInitializationFailed(UnityAdsInitializationError error, string message)
        {
            promise.ReportFail(new Exception($"Unity Ads Initialization Failed: {error.ToString()} - {message}"));
        }
    }

Hello HarisKap,

Unity Ads doesn’t require inheriting Monobehaviour class. Hence, the problem might be related to how you instantiate AdsInitializeTask or in the other code.
To investigate your problem, could you provide some information below?

  1. Unity Editor version
  2. Which platform are you testing? (Ex. iOS, Android)
  3. What device are you testing on? (Ex. iPhone 8, Galaxy s20, etc.)
  4. Could you provide the code where instantiating AdsInitializeTask class and the code of Promise class?
  5. What means freaks out? Also, could you provide any logs related to the problem?

I’ll wait for your response.

Hello,

  1. Unity Editor version is 2021.2.11f1
    2 & 3. Editor for now, not device yet
  2. For initialisation of the previous class the code is
public IPromise Initialize()
{
    var adConfig = configModel.Configuration.AdvertisementConfig;
 
    var initializeTask = new InitializeTask();
    return initializeTask.Initialize(adConfig.GetPlatformID(), adConfig.TestMode).Then(() => OnInitCompleted(adConfig));
}

The promise classes are more than 1 file but its an Action based system on System namespace.

  1. freaks out means, it hangs, like looses the frame and the promise chain just doesn’t move on.

the fix that I applied and seems to work is the following

public void OnInitializationComplete()
{
   if (MainThreadDispatcher.Exists())
   {
      MainThreadDispatcher.Instance.Enqueue(() =>
      {
         promise.Dispatch();
      });
   }
}

I moved the promise dispatch on the main thread. I just want to mention that I don’t have thread issues with other uses of the promise system

Main thread dispatcher is based on https://github.com/PimDeWitte/UnityMainThreadDispatcher
So I would say that the initialisation of the ads system is thread sensitive when is not attached on a MonoBehaviour script.

The 2 screenshots demonstrate how it continues on the initialization chain with the main thread dispatcher while it stucks without it.

Ideally I would expect the thread issue to be handled internally

7951048--1018093--Screenshot 2022-03-09 at 11.42.00.png
7951048--1018096--Screenshot 2022-03-09 at 11.42.12.png

Hello HarisKap,

Thank you for providing the code. I’ve internally discussed this problem with our SDK team and here is the answer.

First, using a promise chain to indicate init complete is wrong, that would just be when the method completes, not when initialization is actually complete, which is why we offer the callback.

Second, it is expected behavior that you are losing the main thread and unity crashes. You probably lose the main thread by executing your code, if you try to execute anything in the unity engine namespace off the main thread, Unity freaks out and crashes.

So, the issue is more related to how you implemented Unity Ads SDK, not from Unity SDK itself.
I hope this answer makes sense. If you have any further questions, please let me know.

Hello,

Thank you for your reply, but I don’t think I understand your response.

Apologies for the following comment but I don’t think that the person you spoke with knows or understands what a promise is…

And just to clarify under the hood on Promise, is nothing more than

public event Action OnComplete;
public event Action<Exception> OnFail;

The OnComplete is triggered on promise.Dispatch() and the OnFail is triggered on promise.ReportFail(new Exception());

The usage of promise is to notify for an async result at some point in the future. Similar to what a “Task” does.

Promise chain is nothing more than a x number of promises linked together. So I will respectfully disagree with the “Wrong” terminology.

I trigger the promise.Dispatch() when I have the result. In Unity Ads SDK I trigger it on your OnInitializationComplete if this is a false event then its a unity issue again…

Additionally as I mentioned on my previous post, I am using this system on different projects with different plugins and async operations including rest calls and I did not have this issue before.

I am attaching 3 screenshots for demonstrating the usage of the Promise Chain. As you can see its just a clean way to initialise the game.

7968258--1021944--Screenshot 2022-03-16 at 15.47.21.png
7968258--1021950--Screenshot 2022-03-16 at 15.46.47.png
7968258--1021953--Screenshot 2022-03-16 at 15.59.20.png