В настоящее время я пытаюсь создать простую многопользовательскую игру с Unity и Socket.IO. Однако на данный момент я сталкиваюсь с некоторыми проблемами. Когда я передал позиционные данные на свой сервер nodejs, все запуталось, потому что Unity решила использовать запятую "," вместо точки "." при работе с поплавками. Я обошел эту проблему, установив для своей культурной зоны в функции запуска значение en-US:
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
Сделав это, я получил правильные данные на сервере. Но при отправке данных другим пользователям они получают неправильные цифры. Например: Игрок 1 меняет позицию x на 1,23 -> другие игроки получают 123 в качестве значения x. Я снова попытался это исправить и просто разделил значение на 100.
Теперь я могу переместить игрока, и другие увидят, как он перемещается в правильную позицию. Но теперь модель игрока просто мерцает. Только когда он стоит на месте, он полностью здесь. Я не уверен, является ли это ошибкой в моем коде, или просто ошибкой Unity, или результатом того, как я дважды открываю один и тот же проект Unity (символическая ссылка). Я надеюсь, что кто-то имеет представление о том, что происходит в моем проекте.
Редактировать:
Серверный код:
socket.on('updatePosition', (data) => {
player.position.x = data.position.x;
player.position.y = data.position.y;
player.position.z = data.position.z;
socket.broadcast.emit('updatePosition', player);
});
Код Unity для отправки новых позиций:
player.position.x = MethodExtensions.twoDecimals(transform.position.x);
player.position.y = MethodExtensions.twoDecimals(transform.position.y);
player.position.z = MethodExtensions.twoDecimals(transform.position.z);
networkIdentity.getSocket().Emit("updatePosition", new JSONObject(JsonUtility.ToJson(player)));
Код Unity для получения новых данных:
On("updatePosition", (E) => {
string id = MethodExtensions.removeQuotes(E.data["id"].ToString());
float x = E.data["position"]["x"].f / 100.0f;
float y = E.data["position"]["y"].f / 100.0f;
float z = E.data["position"]["z"].f / 100.0f;
NetworkIdentity networkIdentity = serverObjects[id];
networkIdentity.transform.position = new Vector3(x, y, z);
});
Я тоже так думал, но я проверил позиции, переданные моему объекту, и они кажутся правильными.
Вы также регистрировали положение объекта и данные из сети. Возможно, некоторые кадры вы не получаете данные и не назначаете (0,0,0) позицию. Также было бы полезно, если бы вы могли поделиться своим кодом.
Вы совершенно правы. Я только что снова проверил свои позиции и не заметил, что иногда округленные позиции, которые я отправляю на сервер, имеют только один десятичный знак. А с другой стороны, я делю их на 100, чтобы работать против странного поведения Unity. Я предполагаю, что мой сервер отправляет правильные данные. Однако я использую расширение socket.io в единстве и действительно не знаю, где регистрировать позиции, полученные с сервера.
Ну, я подозреваю, что это может быть проблема с синхронизацией. Возможно, вы можете сохранить позицию в последнем кадре и не будете перемещать объект, если есть большая разница между полученными данными и позицией последнего кадра.
Странно то, что мой сервер получает данные, например: x = 2,31, а в единстве я получаю обратно x = 231. Поэтому я решил разделить все эти значения на 100. Но я не думал о том, что мой сервер отправит что-то вроде x = 2,3, поэтому в единстве 23 -> / 100 = 0,23. Моя основная проблема в том, что либо мой сервер при отправке, либо единство при получении позиций игнорирует точку.
Ну это проблема. Обходной путь может состоять в том, чтобы разделить число на 100 и проверить, больше ли результат, чем 0. То же самое для 10.
Я не думаю, что это сработает. Например, реальная позиция может быть 2,3, единица получает 23. Но также 0,23 будет 23 в единице.
Ах ты прав? Можете ли вы отправить данные в виде строки и использовать string.split? Для разделения целой и десятичной части
Может быть. Я понял, что проблема заключается в преобразовании строки в JSONObject в единстве. Это происходит, когда ресурс socket.io декодирует отправляемые данные. Там я также увидел, что данные, которые отправляет мой сервер, действительно верны. Теперь мне просто нужно выяснить, что не так с новой функцией JSONObject(String), потому что она, похоже, игнорирует числа с плавающей запятой.
Я нашел решение. Когда функция JSONObject преобразует строку, она учитывает вашу культуру. Поскольку я не из США или где-либо еще, где числа с плавающей запятой пишутся с точкой, он не смог преобразовать число и просто проигнорировал запятую. Теперь он работает отлично. Спасибо за помощь.
Пожалуйста. Я рад, что вы решили проблему.





Судя по картинке, кажется, что это Flickr происходит из-за того, что вы получаете странные данные о местоположении.