#c# #unity3d #dll
Вопрос:
Я написал библиотеку классов за пределами Unity (и поместил ее в Unity в виде библиотеки DLL), в которой я объявил публичное событие, которое я слушаю из своего кода unity. Событие вызывается из библиотеки DLL. Когда событие было вызвано, методы, которые подписываются на событие, выполняются, как я и ожидал, за исключением UnityEngine.Сценография.Диспетчер сцен.LoadScene() не выполняется, а также приводит к тому, что любой код после него не запускается.
using UnityEngine.SceneManagement; using MyDLL; // this namespace has the Client.OnConnected event public class GameManager : MonoBehaviour { void Awake() { Client.OnConnected = () =gt; { Debug.Log("Connected to Server"); SceneManager.LoadScene("Main"); Debug.Log("Main Scene Loaded"); }; } }
Когда Клиент.Вызывается событие OnConnected, я вижу, что «Подключено к серверу» регистрируется, но сцена «Основная» не загружается, а «Основная сцена загружена» не регистрируется.
У кого-нибудь есть какие-либо идеи, почему это происходит и как это обойти?
Ответ №1:
Ваша проблема, скорее всего, заключается в том, что большая часть API Unity может быть вызвана только из основного потока Unity.
Ваше OnConnected
событие, похоже, вызывается асинхронно.
Вам нужно будет отправить этот вызов обратно в основной поток Unity.
Часто используемый шаблон для этого заключается в следующем:
public class GameManager : MonoBehaviour { // A thread safe Queue we can append actions to that shall be executed in the next Update call private readonly ConcurrentQueuelt;Actiongt; _actions = new ConcurrentQueuelt;Actiongt;(); 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(() =gt; { 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 gt; 0) { if(_actions.TryDequeue(out var action)) { action?.Invoke(); } } } }