Поскольку обратные вызовы поступают из неосновного потока, а Unity - это однопотоковая среда, поэтому некоторые API Unity недоступны из неосновных потоков, например, вы не можете использовать GameObject.SetActive или многие другие функции компонентов. кроме основного потока, то, что вам нужно сделать, это сначала отправить обратный вызов в основной поток, а затем будут выполнены все операторы в вашей функции.
Вот как.
1) Простойдиспетчер, который выполняет методы в главном потоке единицы. создайте пустой игровой объект на своей сцене и прикрепите его к нему.
using System;
using System.Collections.Generic;
/// <summary>
/// Helps dispatch task results to the main thread to be able to operate on unity's API like SetActive, enabled etc...
/// </summary>
public class MainThreadDispatcher : MonoBehaviour
{
Queue<Action> jobs = new Queue<Action>();
static MainThreadDispatcher Instance = null;
private void Awake()
{
Instance = this;
}
private void Update()
{
while (jobs.Count > 0)
{
var next = jobs.Dequeue();
if(next != null)
{
next.Invoke();
}
}
}
/// <summary>
/// Dispatches a function to be executed on unity's main thread to be able to use unity's API.
/// </summary>
/// <param name="newJob"></param>
public static void Dispatch(Action newJob)
{
if (newJob == null)
return;
Instance.jobs.Enqueue(newJob);
}
}
2) Отредактируйте закрытый обратный вызов по объявлению для отправки в основной поток.
public void HandleRewardedAdClosed(object sender, EventArgs args)
{
// simply give unity control back.
// you can pick and choose to execute what on main thread,
// but I'm just gonna dispatch the whole block.
MainThreadDispatcher.Dispatch(() =>
{
MonoBehaviour.print("HandleRewardedAdClosed event received");
Debug.Log("{lo} OnClosed called sender = " + sender);
RequestRewardedVideo();
gameManager.CheckForLives();
this.RewardPanel.SetActive(true);
});
}