Почему ошибка вылетает, хотя раньше все ок было.

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 28 фев 2013, 17:27

Приф. Вылетает ошибка
Изображение
get_transform can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.

при выполнении метода ProcessReceive. раньше такого вроде не было. все норм работало. сегодня первый раз вижу эту ошибку.
Вот код
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;

public class Client: MonoBehaviour {

        private static Socket socket;
        private static SocketAsyncEventArgs SockAsyncEventArgs; // объект для асинхронной операции на сокете

        private static byte[] buff;
        private static int i = 0;
       
               
           
                public GameObject me;
                public GameObject he;
                private Transform HisTrans;
                private static Transform hist;
                private static Transform MyTrans;
                private static Transform oldTrans;
                private static Transform newTrans;
                private static bool sw=false;

        private static void Init()
        {
                Debug.Log("Init");
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            buff = new byte[256];
            SockAsyncEventArgs = new SocketAsyncEventArgs();
            // подписываемся на завершение асинхронного соединения
            SockAsyncEventArgs.Completed += SockAsyncArgs_Completed;
        }
       

        private static void SockAsyncArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
                Debug.Log("Completed");
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Connect:
                    ProcessConnect(e);
                    break;
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
            }
        }

        private static void Start_Connect(string address, int port)
        {
                Debug.Log("Start_Connect");
            SockAsyncEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
            ConnectAsync(SockAsyncEventArgs);
        }

        private static void ConnectAsync(SocketAsyncEventArgs e)
        {
                Debug.Log("ConnectAsync");
            bool willRaiseEvent = socket.ConnectAsync(e);
            if (!willRaiseEvent)
                ProcessConnect(e);
        }

        private static void ProcessConnect(SocketAsyncEventArgs e)
        {
                Debug.Log("ProcessConnect");
            if (e.SocketError == SocketError.Success)
            {
                SockAsyncEventArgs.SetBuffer(buff, 0, buff.Length);
                               
                                sw=true;
               
                               
            }
            else
                Debug.Log("Lost connection with " + e.RemoteEndPoint.ToString());

        }

        private static void SendAsync(byte[] data)
        {
                Debug.Log("SendAsync");
            if (socket.Connected && data.Length > 0)
            {
                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.SetBuffer(data, 0, data.Length);
                e.Completed += SockAsyncArgs_Completed;
                bool willRaiseEvent = socket.SendAsync(e);
                // Debug.Log("bytes sent: "+data.Length);
            }
        }

        private static void ProcessSend(SocketAsyncEventArgs e)
        {
                Debug.Log("ProcessSend");
            try
            {
                if (e.SocketError == SocketError.Success)
                {
                    ReceiveAsync(SockAsyncEventArgs);
                }
                else
                {
                    Debug.Log("Not sended");
                }
            }
            catch (Exception ex)
            {
                Debug.Log("ProcessSend: " + ex.Message);
            }
        }

        private static void ReceiveAsync(SocketAsyncEventArgs e)
        {
                Debug.Log("ReceiveAsync");
            try
            {
                bool willRaiseEvent = socket.ReceiveAsync(e);
                if (!willRaiseEvent)
                    ProcessReceive(e);
            }
            catch (Exception ex)
            {
                Debug.Log("ReceiveAsync: " + ex.Message);
            }
        }
 

Синтаксис:
Используется csharp
private static void ProcessReceive(SocketAsyncEventArgs e)
        {
                Debug.Log("PrecessReceive");

            if (e.SocketError == SocketError.Success)
            {
                try
                {
                                Debug.Log("receive bytes: "+e.BytesTransferred);
                                       
                                float x = BitConverter.ToSingle(e.Buffer,0);
                                        float y = BitConverter.ToSingle(e.Buffer,4);
                                        float z = BitConverter.ToSingle(e.Buffer,8);
                                float x_rot = BitConverter.ToSingle(e.Buffer,12);
                                float y_rot = BitConverter.ToSingle(e.Buffer,16);
                                float z_rot = BitConverter.ToSingle(e.Buffer,20);
                                float w_rot = BitConverter.ToSingle(e.Buffer,24);
                                        hist.transform.position = new Vector3(x,y,z);
                                        hist.transform.rotation = new Quaternion(x_rot,y_rot,z_rot,w_rot);
                               
                        //MyTrans.BroadcastMessage("AssignNewTrans",e.Buffer);
                    //string s = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred); //получаем идентификатор команды
                    //Debug.Log(s);
                   
                }
                catch (Exception ex)
                {
                    Debug.Log("ProcessReceive: " + ex.Message);//
                }

            }

        }

       
       
                private void AssignNewTrans(byte[] b)
        {
                Debug.Log("AssignNewTrans 1");
                newTrans.position = new Vector3(
                        BitConverter.ToSingle(b,0),
                        BitConverter.ToSingle(b,4),
                        BitConverter.ToSingle(b,8)
                        );
                newTrans.rotation = new Quaternion(
                        BitConverter.ToSingle(b,12),
                        BitConverter.ToSingle(b,16),
                        BitConverter.ToSingle(b,20),
                        BitConverter.ToSingle(b,24)
                        );
                        Debug.Log("AssignNewTrans 2");
                        Transform t = InterpolateTransform(newTrans,oldTrans,10);
                        AssignInterTrans(t);
                       
       
        }
        private static Transform InterpolateTransform(Transform n, Transform o,float rate)
        {
                Transform t = MyTrans;
                t.position=new Vector3(
                        Mathf.Lerp(o.position.x,n.position.x,1/rate)-o.position.x,
                        Mathf.Lerp(o.position.y,n.position.y,1/rate)-o.position.y,
                        Mathf.Lerp(o.position.z,n.position.z,1/rate)-o.position.z
                        );
                t.rotation=new Quaternion(
                        Mathf.Lerp(o.rotation.x,n.rotation.x,1/rate)-o.rotation.x,
                        Mathf.Lerp(o.rotation.y,n.rotation.y,1/rate)-o.rotation.y,
                        Mathf.Lerp(o.rotation.z,n.rotation.z,1/rate)-o.rotation.z,
                        Mathf.Lerp(o.rotation.w,n.rotation.w,1/rate)-o.rotation.w
                        );
                return t;
        }
       
        public void AssignInterTrans(Transform t)
        {
                StartCoroutine("Inter",t);
        }
       
        IEnumerator Inter(Transform t)
        {
                for(int i=0;i>10; i++)
                {
                        HisTrans.position=new Vector3(
                                HisTrans.position.x+t.position.x,
                                HisTrans.position.y+t.position.y,
                                HisTrans.position.z+t.position.z
                                );
                        HisTrans.rotation=new Quaternion(
                                HisTrans.rotation.x+t.rotation.x,
                                HisTrans.rotation.y+t.rotation.y,
                                HisTrans.rotation.z+t.rotation.z,
                                HisTrans.rotation.w+t.rotation.w                       
                        );
                        yield return new WaitForSeconds(1f/10f);
                }
        }
                               
        void Start()
        {
               
                Debug.Log("Start");
                        MyTrans = me.transform;
                        oldTrans = he.transform;
                        newTrans = oldTrans;
                HisTrans = he.transform;
                hist=he.transform;
                 Init(); //подготовка соединения  с сервером
         Start_Connect("127.0.0.1", 9095); //соединяемся с сервером
               
                StartCoroutine(SendFunc());
                StartCoroutine(Res());
               
       
        }
       
        IEnumerator SendFunc()
        {
                Debug.Log("SendFunc");
                while(true)
                {
                        if(sw){
                Debug.Log("send");
               
                SendAsync(Get_Transform_Data());
                               
                       
                        }
               
                else
                        Debug.Log("didnt sent");
                        yield return new WaitForSeconds(1);
                }
                       
        }
       
         IEnumerator Res()
        {
                Debug.Log("Res");
         
                while (true)
                {
                        try{
                    if (socket.Available > 0) //если пришли данные
                    {
                      /*  i++;
                        Debug.Log("i = "+i);
                        SocketAsyncEventArgs SockAsyncEventArgs1 =new SocketAsyncEventArgs();
                        SockAsyncEventArgs1.Completed += SockAsyncArgs_Completed;*/


                        //Thread.Sleep(500);
                        ProcessSend(SockAsyncEventArgs); // получаем их
                    }
                               
                }
           
            catch (Exception e)
            {
                Debug.Log("res: " + e.Message);
            }
                        yield return new WaitForSeconds(Time.deltaTime);
                 }
       
        }
       
        byte[] Get_Transform_Data()
        {
                Debug.Log("Get_Transform_Data");
                byte[] b = new byte[28];
                BitConverter.GetBytes(MyTrans.position.x).CopyTo(b,0);
                BitConverter.GetBytes(MyTrans.position.y).CopyTo(b,4);
                BitConverter.GetBytes(MyTrans.position.z).CopyTo(b,8);
               
                BitConverter.GetBytes(MyTrans.rotation.x).CopyTo(b,12);
                BitConverter.GetBytes(MyTrans.rotation.y).CopyTo(b,16);
                BitConverter.GetBytes(MyTrans.rotation.z).CopyTo(b,20);
                BitConverter.GetBytes(MyTrans.rotation.w).CopyTo(b,24);
               
                return b;
        }
       
}
 

Это все один код, просто я проблемный метод выделил таким образом, он вначале второй части.
в чем проблема?? как решить ее? спс
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Woolf 28 фев 2013, 19:04

в чем проблема?? как решить ее?

А что, по тексту ошибки не понятно, как её решить? Написано же, что работа с трансформом возможно только из главного потока. Если раньше это у вас работало, значит это был баг в юнити, который закрыли с новой версией.
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 28 фев 2013, 19:52

Woolf писал(а):
в чем проблема?? как решить ее?

А что, по тексту ошибки не понятно, как её решить? Написано же, что работа с трансформом возможно только из главного потока. Если раньше это у вас работало, значит это был баг в юнити, который закрыли с новой версией.

в том-то и дело, что версию Юнити я не менял
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение seaman 28 фев 2013, 20:20

Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 28 фев 2013, 20:33

seaman писал(а):Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.

так код целый, я просто разделил его, чтобы вам было проще находить метод в котором возникает ошибка, а именно
Синтаксис:
Используется csharp
ProcessReceive
правда, она не совсем в моем коде возникает. при нажатии на ошибку, внизу окна консоли, вот, что написано
Изображение
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение seaman 28 фев 2013, 21:39

Ну так, умозрительно, разобраться не просто. Не нравятся статические переменные и их инициализация. Я бы все статическое вынес из класса, наследованного от монобехевиор, в отдельный статический класс. А дальше уж думал, если ошибка останется.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 28 фев 2013, 21:50

seaman писал(а):Ну так, умозрительно, разобраться не просто. Не нравятся статические переменные и их инициализация. Я бы все статическое вынес из класса, наследованного от монобехевиор, в отдельный статический класс. А дальше уж думал, если ошибка останется.

окей спс. попробую
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Woolf 28 фев 2013, 21:52

seaman писал(а):Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.


А сокет на другом треде висит. И он из этого другого треда пытается обработать команду, а потом изменить трансформ. юня и ругается. Как вариант - можно полученные пакеты складывать в списочек, естественно синхронизировать все аккуратно, а обрабатывать их уже на Update - выбирать синхронизированно из списка и делать процесс.
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 28 фев 2013, 22:36

Woolf писал(а):
seaman писал(а):Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.


А сокет на другом треде висит. И он из этого другого треда пытается обработать команду, а потом изменить трансформ. юня и ругается. Как вариант - можно полученные пакеты складывать в списочек, естественно синхронизировать все аккуратно, а обрабатывать их уже на Update - выбирать синхронизированно из списка и делать процесс.

в списочек типа List? эт значит я получаю данные от сервера, потом пихаю эти данные в public static List<Transform>, а Update изымает из этого списка Transform и применяет к объекту?
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 28 фев 2013, 23:01

слушайте, я тут спросил на одном форуме, там люди злые и ниче не объясняют подробно, но сказали, что чтобы из треда А вызвать метод, который в треде Б - нужно юзать - invoke. Поясните плиз, как именно его юзать? а-то я нашел класс Controle.Invoke, так оно для форм
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 01 мар 2013, 11:00

Woolf писал(а):
seaman писал(а):Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.


А сокет на другом треде висит. И он из этого другого треда пытается обработать команду, а потом изменить трансформ. юня и ругается. Как вариант - можно полученные пакеты складывать в списочек, естественно синхронизировать все аккуратно, а обрабатывать их уже на Update - выбирать синхронизированно из списка и делать процесс.

спс чювак, я сделал так, как ты написал, и все работает XD ты самый крутой после Коны-тян! XD
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Woolf 01 мар 2013, 13:07

Chaz писал(а):
Woolf писал(а):
seaman писал(а):Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.


А сокет на другом треде висит. И он из этого другого треда пытается обработать команду, а потом изменить трансформ. юня и ругается. Как вариант - можно полученные пакеты складывать в списочек, естественно синхронизировать все аккуратно, а обрабатывать их уже на Update - выбирать синхронизированно из списка и делать процесс.

спс чювак, я сделал так, как ты написал, и все работает XD ты самый крутой после Коны-тян! XD


Про lock не забыли? А то могут быть траблы с синхронизацией, если тред сокета попытается добавить пакет, а главный тред как раз будет брать оттуда данные.
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Почему ошибка вылетает, хотя раньше все ок было.

Сообщение Chaz 01 мар 2013, 14:47

Woolf писал(а):
Chaz писал(а):
Woolf писал(а):
seaman писал(а):Где другой поток то? Я сокеты не очень знаю. Может в socket.SendAsync(e);? Или в подобной асинхронной функции? Иначе не понятна сама ошибка.
Лучше бы привести строку в которой ошибка и код не кусками - без разрывов.


А сокет на другом треде висит. И он из этого другого треда пытается обработать команду, а потом изменить трансформ. юня и ругается. Как вариант - можно полученные пакеты складывать в списочек, естественно синхронизировать все аккуратно, а обрабатывать их уже на Update - выбирать синхронизированно из списка и делать процесс.

спс чювак, я сделал так, как ты написал, и все работает XD ты самый крутой после Коны-тян! XD


Про lock не забыли? А то могут быть траблы с синхронизацией, если тред сокета попытается добавить пакет, а главный тред как раз будет брать оттуда данные.

забыли xD терь добавлю, спс
Chaz
Адепт
 
Сообщения: 1412
Зарегистрирован: 07 апр 2012, 11:24


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 25