C # / Unity3D - Функция не работает одинаково при вызове из разных функций - PullRequest
0 голосов
/ 14 января 2019

Я использую Unity 3D в качестве клиента приложения C # с использованием сокетов TCP и UDP.

Вот функция:

public void updateCharacterPosition(CharacterPosition position, int characterId, int cnnId)
{
    if (Character.SceneLoaded != true)
        return;

    if (cnnId != ClientWorldServer.connectionId)
    {
        Debug.Log("HERE!");
        GameObject startPoint = GameObject.Find("CharactersOnline/" + characterId.ToString());
        Debug.Log("HERE 1: " + GameObject.Find("CharactersOnline").transform.name);
        Debug.Log("HERE 2: " + startPoint.transform.name);
        GameObject endPoint = new GameObject();
        endPoint.transform.position = new Vector3(position.x, position.y, position.z);
        GameObject.Find("CharactersOnline/" + characterId.ToString()).transform.position = Vector3.Lerp(startPoint.transform.position, endPoint.transform.position, Time.deltaTime);

        //Updating Clients ram of the character's position
        Character.characterDetails[characterId].characterPosition.x = position.x;
        Character.characterDetails[characterId].characterPosition.y = position.y;
        Character.characterDetails[characterId].characterPosition.z = position.z;
        //Destroy(endPoint);
    }
}

Вот две функции, которые вызывают эту функцию:

Функция получения данных TCP:

    private void OnIncomingData(string data)
    {
        JsonData json = JsonConvert.DeserializeObject<JsonData>(data);
        string prefix = json.header.Substring(0, 2);

        if (prefix != "0x")
        {
            Debug.Log("Unknown packet: " + data + "\n");
        }
        else
        {
            string header = json.header.Substring(2);
            int conId = json.connectionId;
            //Debug.Log("Header:" + header);
            switch (header)
            {
                default:
                    Debug.Log("Unknown packet: " + data + "\n");
                    break;
                case "000":
                    Debug.Log("Empty header received: " + json.header + "\n");
                    break;
                case "001":

                    if (connectionId == 0)
                    {
                        connectionId = conId;
                        Debug.Log("Connection ID: " + connectionId + "\n");
                        //After we have connected to TCP Stream now let's connect to UDP.
                        ConnectUDP();

                    }
                    break;
                    case "004":
                        DisplayCharacterSelects(json.data, connectionId);
                    break;
                case "005":
                    CharacterData charData = new CharacterData();

                    string jsonData = JsonConvert.SerializeObject(json.data, Formatting.None);
                    charData = JsonConvert.DeserializeObject<CharacterData>(jsonData);
                    playerSpawner.SpawnPlayer(playerSpawner,charData);
                    break;
                case "006":
                    playerSpawner.SpawnOnlinePlayers(playerSpawner,json.data);
                    break;
                case "007":
                    CharacterLogout(json.data);
                    break;
                case "008":
                    CharacterPosition position = new CharacterPosition();
                    position.x = float.Parse(json.data["position.x"].ToString());
                    position.y = float.Parse(json.data["position.y"].ToString());
                    position.z = float.Parse(json.data["position.z"].ToString());
                    character.updateCharacterPosition(position, Convert.ToInt32(json.data["characterId"].ToString()), conId);
                    break;
                case "009":
                    character.updateCharacterRotation(json.data, conId);
                    break;    
            }
            Debug.Log("World Server: " + data + " TIME: " + Timer);

        }

    }

А вот функция получения данных UDP:

    private void UDPReceive()
    {
        _socket.BeginReceiveFrom(state.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv = (ar) =>
        {
            State so = (State)ar.AsyncState;
            int bytes = _socket.EndReceiveFrom(ar, ref epFrom);
            _socket.BeginReceiveFrom(so.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv, so);
            Debug.Log("UDP World: " + Encoding.ASCII.GetString(so.buffer, 0, bytes));

            string receivedData = Encoding.ASCII.GetString(so.buffer, 0, bytes);

            JsonData json = JsonConvert.DeserializeObject<JsonData>(receivedData);
            string prefix = json.header.Substring(0, 2);

            if (prefix != "3x")
            {
                Debug.Log("Unknown packet: " + receivedData + "\n");
            }
            else
            {
                string header = json.header.Substring(2);
                int conId = json.connectionId;
                //Debug.Log("Header:" + header);
                switch (header)
                {
                    default:
                        Debug.Log("Unknown packet: " + receivedData + "\n");
                        break;
                    case "001":
                        Debug.Log("Data received: " + receivedData + "\n");
                        break;
                    case "002":
                    CharacterPosition position = new CharacterPosition();
                    position.x = float.Parse(json.data["position.x"].ToString());
                    position.y = float.Parse(json.data["position.y"].ToString());
                    position.z = float.Parse(json.data["position.z"].ToString());
                    character.updateCharacterPosition(position, Convert.ToInt32(json.data["characterId"].ToString()), conId);
                    break;
                    case "003":
                    character.updateCharacterRotation(json.data, conId);
                    break;
                }
            }
        }, state);
    }

Что происходит. Когда updateCharacterPosition() вызывается из OnIncomingData, который является прослушивателем TCP, функция работает на 100%, как и предполагалось.

Однако, когда функция updateCharacterPosition() вызывается из UDPReceive(), функция updateCharacterPosition(), похоже, останавливает свое выполнение в GameObject startPoint = GameObject.Find("CharactersOnline/" + characterId.ToString());

строки:

Debug.Log("HERE 1: " + GameObject.Find("CharactersOnline").transform.name);
Debug.Log("HERE 2: " + startPoint.transform.name);

Не показывает никаких результатов. Как будто их там нет. В консоли Unity не отображаются ошибки, так как она не может найти объект или что-то еще, и все же Debug.Log ничего не показывает. Единственное, что вы можете увидеть в консоли, это следующая строка:

Debug.Log("HERE!");

Кажется, все, что ниже этой строки, не работает и не выдает никаких ошибок. Есть ли у вас какие-либо подсказки, почему возникает эта проблема и как я могу ее решить?

Обе функции OnIncomingData и UDPReceive находятся в одном классе.

1 Ответ

0 голосов
/ 14 января 2019

Я не уверен, почему версия UDP не работает, однако я могу пролить свет на то, почему определенные части кода не работают.

В Unity есть то, что вы можете считать «полезной» функцией, когда всякий раз, когда выполнение сталкивается с ошибкой, которая в противном случае завершила бы программу, она вместо этого заканчивает текущий набор команд и продолжит работу в следующей возможной точке, не сообщая об ошибках приставка. Что касается того, почему они не предоставляют ошибку, я не могу вам сказать, но они этого не делают.

Таким образом, с точки зрения вашей программы, код, вероятно, вылетает в строке:

GameObject startPoint = GameObject.Find("CharactersOnline/" + characterId.ToString());

при попытке получить GameObject. В этом случае ваш код дает сбой, Unity завершает выполнение и затем переходит к следующей возможной вещи, которую он может запустить из класса Monobehavior, все время делая вид, что ничего не пошло не так.

Мое предложение для исправления этого - бросить его в блок try / catch и распечатать его, если он потерпит неудачу. Предполагая, что я прав, вы сможете увидеть распечатанное сообщение и начать отладку на основе данных, к которым вы можете получить доступ в данный момент.

...