Избранное Все заметки Главная
1 заметка с тегом

can only be called from the main thread

Unity API из другого потока (can only be called from the main thread)

Наверняка многие из вас пытались вызывать методы из api юньки или обращаться к объектам из другого потока.
Если ещё не пробывали — попробуйте, компилятор заорёт примерно такой ошибкой — can only be called from the main thread
Вообщем-то погуглив я понял,что не я один с этим встречался,поэтому на будущее оставлю решение здесь,может кому пригодится. Совет нашел на SO,но ссылку привести не смогу,утерял.

Условие простое, хотим работать с unity api — проворачиваем свои делишки только в главном потоке,иначе никак.
Поскольку метод Update крутится в главном потоке,проверку будем производить там. Поехали...
Итак, допустим я в дополнительном потоке получаю сообщения от сервера. Мне необходимо каждое сообщение добавлять в Text UI. Если попытаюсь из дополнительного потока поработать с UI,то получу ошибку,исправляется следующим образом:

Для начала объявим в нашем скрипте очередь из делегатов и некоторые промежуточные переменные

private Queue<Action> mainThread = new Queue<Action>(); 
private string data = null;

Теперь для примера напишем метод,который будет взаимодействовать с UI.

private void OnWriteMessageChat()
    {
        if (data != null)
        {
            chatfield.text += data + "\n";
            data = null;
        }
    }

А это пускай будет тот самый метод,который принимает от сервера сообщения :

private void Communication()
                        {
data = "msg from server";
// бла бла , допустим мы уже получили сообщение от сервера и храним её в переменной data ,которую изначально объявили в теле класса.

                                mainThread.Enqueue(new Action(OnWriteMessageChat));
                                Debug.Log("Делегат добавлен в очередь");

                            }

У mainThread есть метод Enqueue,которые добавляет наши делегаты в очередь.
Остается только достать из очереди делегат и вызвать Invoke(). Для этого пригодится Update (я уже упоминал его в начале,не забыли?)

private void Update()
    {
        if(mainThread.Count > 0)
        {
            mainThread.Dequeue().Invoke();
        }

    }

Вот и всё,статья получилось довольно сжатой,но, думаю , смысл понятен.

2018   can only be called from the main thread   unity API