I have written a class library outside of Unity (and put it in Unity as a DLL) in which I've declared a public event that I listen to from my unity code. The event is being invoked from within the DLL. When the event has been invoked the methods that subscribe to the event are being executed as I expect, with the exception that UnityEngine.SceneManegement.SceneManager.LoadScene() is not running, as well as causing any code after it to not run.
using UnityEngine.SceneManagement;
using MyDLL; // this namespace has the Client.OnConnected event
public class GameManager : MonoBehaviour
{
void Awake()
{
Client.OnConnected = () => {
Debug.Log("Connected to Server");
SceneManager.LoadScene("Main");
Debug.Log("Main Scene Loaded");
};
}
}
When the Client.OnConnected event is invoked, i can see the "Connected to Server" being logged but the scene "Main" is not being loaded and "Main Scene Loaded" is not being logged.
Does anyone have any idea why this is happening and how to work around it?
CodePudding user response:
Your issue is most probably that most of the Unity API can only be called from the Unity main thread.
Your OnConnected
event seems to be called asynchronously.
You will need to dispatch that call back into the Unity main thread.
An often used pattern for this is the following:
public class GameManager : MonoBehaviour
{
// A thread safe Queue we can append actions to that shall be executed in the next Update call
private readonly ConcurrentQueue<Action> _actions = new ConcurrentQueue<Action>();
void Awake()
{
Client.OnConnected = OnClientConnected;
}
private void OnClientConnected()
{
// Instead of immediately exciting the callback append it to the
// actions to be executed in the next Update call on the Unity main thread
_actions.Enqueue(() =>
{
Debug.Log("Connected to Server");
SceneManager.LoadScene("Main");
Debug.Log("Main Scene Loaded");
};
}
// In the main thread work of the dispatched actions
private void Update ()
{
while(_actions.Count > 0)
{
if(_actions.TryDequeue(out var action))
{
action?.Invoke();
}
}
}
}