Run Callbacks in Main Unity Thread
Callbacks in Appodeal plugin are executed in the main Android or iOS thread (not in the main Unity thread). What does it mean for you? It’s not recommended to perform any UI changes (change colours, positions, sizes, texts and so on) directly in our callback functions.
It's important to understand that it's not possible to receive callbacks in main thread while fullscreen advertising
is shown. This is because Unity pause main thread if game scene is out of screen. That’s why your script will receive
some callbacks (like OnInterstitialShown
or OnRewardedVideoFinished
) in main thread only after closing fullscreen
advertising. But the same callbacks work without such delays in Android and iOS main threads.
So, how to react on Appodeal events to prevent multithreading problems? The simplest way is to use flags and Update
method of MonoBehaviour
class:
- UPM Distribution
- Manual Distribution
public class SomeClass : MonoBehaviour
{
bool videoFinished = false;
double rewardAmount;
string rewardName;
public void OnRewardedVideoFinished(object sender, RewardedVideoFinishedEventArgs e)
{
rewardAmount = e.Amount;
rewardName = e.Currency;
// It's important to set flag to true only after all required parameters
videoFinished = true;
}
// Update method always performs in the main Unity thread
void Update()
{
if(videoFinished)
{
// Don't forget to set flag to false
videoFinished = false;
// Do something with rewardAmount and rewardName
}
}
}
public class SomeClass : MonoBehaviour, IRewardedVideoAdListener
{
bool videoFinished = false;
double rewardAmount;
string rewardName;
public void onRewardedVideoFinished(double amount, string name)
{
rewardAmount = amount;
rewardName = name;
// It's important to set flag to true only after all required parameters
videoFinished = true;
}
// Update method always performs in the main Unity thread
void Update()
{
if(videoFinished)
{
// Don't forget to set flag to false
videoFinished = false;
// Do something with rewardAmount and rewardName
}
}
}
Other, maybe more comfortable way is to use UnityMainThreadDispatcher. To use it:
- Download script and prefab.
- Import downloaded files to your project.
- Add
UnityMainThreadDispatcher.prefab
to your scene (or to all scenes, where you want to make UI changes after Appodeal callbacks). - Use
UnityMainThreadDispatcher.Instance().Enqueue()
method to perform changes:
- UPM Distribution
- Manual Distribution
public void OnRewardedVideoFinished(object sender, RewardedVideoFinishedEventArgs e)
{
UnityMainThreadDispatcher.Instance().Enqueue(()=> {
Debug.Log($"Appodeal. Video Finished: {e.Amount} {e.Currency}")
});
}
public void onRewardedVideoFinished(double amount, string name)
{
UnityMainThreadDispatcher.Instance().Enqueue(()=> {
Debug.Log($"Appodeal. Video Finished: {amount} {name}")
});
}
And finally, the official way to send message to Unity Main thread is UnitySendMessage
. It’s platform dependent,
so it’s required to make changes in Android native code and iOS native code.
You can find more information in the official unity documentation for Android and iOS.