Unity: синхронизация вращения по сети на выделенном сервере - PullRequest
0 голосов
/ 06 декабря 2018

Вероятно, об этом спрашивали десятки раз, но я не могу найти ответ нигде.

У меня есть выделенный сервер для космической игры, написанной на консольном приложении C #.Проблемы, с которыми я сталкиваюсь, заключается в синхронизации вращений GameObject.Я подозреваю, что проблема связана с блокировкой карданного подвеса, но я не уверен.

Здесь у меня есть контроллер движения / вращения игрока:

public class PlayerMovement : MonoBehaviour {
    [SerializeField] float maxSpeed = 40f;
    [SerializeField] float shipRotationSpeed = 60f;

    Transform characterTransform;

    void Awake()
    {
        characterTransform = transform;
    }

    void Update()
    {
        Turn();
        Thrust();
    }

    float Speed() {
        return maxSpeed;
    }

    void Turn() {
        float rotX = shipRotationSpeed * Time.deltaTime * CrossPlatformInputManager.GetAxis("Vertical");
        float rotY = shipRotationSpeed * Time.deltaTime * CrossPlatformInputManager.GetAxis("Horizontal");

        characterTransform.Rotate(-rotX, rotY, 0);
    }

    void Thrust() {
        if (CrossPlatformInputManager.GetAxis("Move") > 0) {
            characterTransform.position += shipTransform.forward * Speed() * Time.deltaTime * CrossPlatformInputManager.GetAxis("Move");
        }
    }
}

Этот скрипт применяется к моему персонажуобъект, который является кораблем.Обратите внимание, что объект персонажа имеет дочерний объект, который является самим кораблем и имеет фиксированное вращение и положение, которые не меняются.Когда персонаж перемещается / поворачивается, я отправляю на сервер следующее: положение (x, y, z) и вращение (x, y, z, w).

Теперь вот фактический скрипт, который получает сетевой пакетинформация и обновления других игроков в игре:

public class CharacterObject : MonoBehaviour {
    [SerializeField] GameObject shipModel;

    public int guid;
    public int characterId;
    public string name;
    public int shipId;

    Vector3 realPosition;
    Quaternion realRotation;

    public void Awake() {
    }

    public int Guid { get { return guid; } }
    public int CharacterId { get { return characterId; } }

    void Start () {
        realPosition = transform.position;
        realRotation = transform.rotation;
    }

    void Update () {
        // Do nothing
    }

    internal void LoadCharacter(SNCharacterUpdatePacket cuPacket) {
        guid = cuPacket.CharacterGuid;
        characterId = cuPacket.CharacterId;
        name = cuPacket.CharacterName;
        shipId = cuPacket.ShipId;
        realPosition = new Vector3(cuPacket.ShipPosX, cuPacket.ShipPosY, cuPacket.ShipPosZ);
        realRotation = new Quaternion(cuPacket.ShipRotX, cuPacket.ShipRotY, cuPacket.ShipRotZ, cuPacket.ShipRotW);
        UpdateTransform();

        Instantiate(Resources.Load("Ships/Ship1/Ship1"), shipModel.transform);
    }

    internal void UpdateCharacter(SNCharacterUpdatePacket cuPacket) {
        realPosition = new Vector3(cuPacket.ShipPosX, cuPacket.ShipPosY, cuPacket.ShipPosZ);
        realRotation = new Quaternion(cuPacket.ShipRotX, cuPacket.ShipRotY, cuPacket.ShipRotZ, cuPacket.ShipRotW);
        UpdateTransform();
    }

    void UpdateTransform() {
        transform.position = Vector3.Lerp(transform.position, realPosition, 0.1f);
        transform.rotation = Quaternion.Lerp(transform.rotation, realRotation, 0.5f);
    }
}

Видите ли вы что-нибудь не так с кодом?

Мой опыт игры с двумя игроками следующий: Когда я начинаю игру су двух игроков они появляются в одном месте (0,0,0) и в одном и том же повороте (0,0,0).Допустим, что другой игрок непрерывно вращается только вокруг оси X.То, что я испытываю, это:

  1. Первые 90 градусов.вращения это делает хорошо.
  2. Следующие 180 град.вращения объекта остается на месте
  3. последние 90 град.вращения рендерится нормально

В первой версии я не отправлял значение 'Qu' 'w', а затем добавил его во второй версии, и это не помогло.Обратите внимание, что нет ограничений на вращение, и пользователи могут вращаться бесконечно во всех направлениях.Кстати, позиционирование работает отлично.

Возможно, я не совсем понимаю Quaternions, но я подумал, что они преследуют цель избежать проблемы с блокировкой карданного подвеса.

Любая помощь будет признательна.

1 Ответ

0 голосов
/ 13 декабря 2018

Чтобы ответить на мой собственный вопрос.Я использовал transform.localEulerAngles вместо transform.rotation, и все, кажется, работает нормально.

Теперь я не уверен только в том, может ли блокировка карданного подвеса произойти с этим изменением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...