#Unable to sync rotations between client and host

7 messages · Page 1 of 1 (latest)

pastel juniper
#

Hello, I am trying to sync the rotation of the player in a first person rigidbody controller over network using client-side prediction. The first person camera I am using is only spawned on the client who owns the player.

I am using FishNet 3.10.8R, with the version 1 CSP system.

An issue I ran into was that collecting the mouse:delta Vector2 for y-axis rotation in the TickManager.OnTick() callback led to rotation that was not smooth. A solution I found was to sum the mouse:delta vectors in the update method of the client who owns the player I am trying to rotate, and then sending a single Vector2 containing the sum of those mouse:delta vectors over the network in my IReplicateData in the [Replicate] method. However, when doing this, the client's rotation is no longer synced over network.

Here is the update method on the camera controller which sums the net mouse:delta:

    {
        if (_playerInputManager != null)

        {
            Vector2 mouseDelta = _playerInputManager.GetMouseDelta();
            if (mouseDelta != Vector2.zero)
            {
                _netMouseMovement += mouseDelta * Time.deltaTime * _playerInputManager.GetMouseSensitivity();
            }
        }
    
}```

And here is how I am gathering the inputs: 

```    private void GatherInputs(out MoveData data)
    {
        data = default;

        Vector2 strafeDirection = _playerInputManager.GetStrafeDirection();
        bool isJumping = _playerInputManager.IsJumping();
        var netMouseMovement = _firstPersonCameraController.GetNetMouseMovement();
        _firstPersonCameraController.ResetNetMouseMovement();

        if ((strafeDirection == Vector2.zero) && (isJumping == false) && (netMouseMovement == Vector2.zero))
        {
            return;
        }

        data = new MoveData()
        {
            IsJumping = isJumping,
            StrafeDirection = strafeDirection,
            NetMouseMovement = netMouseMovement,
        };
}```
#

For further reference, this is the [Replicate] Move() method.

    private void Move(MoveData data, bool asServer, Channel channel = Channel.Unreliable, bool replaying = false)
    {
        if (_isFullyLoaded)
        {
            Vector3 forward = transform.forward;
            Vector3 left = Vector3.Cross(forward, transform.up);

            var netMouseMovement = data.NetMouseMovement;

            xAxisHeadRotation -= netMouseMovement.y;
            xAxisHeadRotation = Math.Clamp(xAxisHeadRotation, -1 * xAxisHeadRotationLimit, xAxisHeadRotationLimit);

            yAxisRotation += netMouseMovement.x;

            transform.rotation = Quaternion.Euler(0, yAxisRotation, 0);

            Vector3 strafeForce = (-1 * data.StrafeDirection.x * left + data.StrafeDirection.y * forward) * strafeForceMagnitude;

            _rigidbody.AddForce(strafeForce);

            if (base.IsOwner)
            {
                Vector3 cameraSetPoint = this.transform.position + _firstPersonCameraController.GetOffset();

                if (Vector3.Distance(cameraSetPoint, _firstPersonCamera.transform.position) > _firstPersonCameraController.GetPositionTolerance())
                {
                    _firstPersonCamera.transform.position = cameraSetPoint;

                }

                _firstPersonCamera.transform.rotation = transform.rotation;
            }
        }
    }

And this is the [Reconciliation] method:

    {
        transform.position = data.Position;
        transform.rotation = data.Rotation;
        _rigidbody.velocity = data.Velocity;
        _rigidbody.angularVelocity = data.AngularVelocity;
    }

I am not syncing the rotation of the camera, because the camera is only a local object. Each client has one camera.

#

It is important to note that the syncing of the transform.positions of the clients is working perfectly, and that the client host rotation is always synced with all the other clients. It is only the clients which are out of sync with each other and the client host.

#

I also reset the private Vector2 _netMouseMovement in my CameraController every time the TimeManager.OnTick() method is called. Therefore that variable should only hold the net mouse:delta for all the Update() frames between TimeManager ticks. By multiplying the mouse:delta vectors with Time.timeDelta before summing them, I thought that using the Update() method for tracking mouse movement would work sufficiently. The rotations are much smoother as is, but out of sync.

#

Both the spawned camera, and the associated player are root objects on the scene, so using transform.rotation should be the same as using transform.localRotation

#

Im almost wondering if the issue lies in how the move method is handling replaying

pastel juniper
#

I bet its because Im not syncing the variable yAxisRotation in the reconciliation method. Let me try that