Wheel rotation synchronization photon

I’m trying to synchronize the rotation of the wheels so that other players can watch it. I send the position and rotation, synchronization occurs using RaiseEvent, everything is not synchronized correctly. Firstly, the wheels of another player are twitching when moving, I understand that this may occur with bandwidth or something else, but how can this be fixed? Secondly, the wheels do not rotate, they literally retain their original rotation relative to the machine, that is, when turning, their rotation does not follow the rotation of the machine, but literally remains static, as if the machine turns, but the wheels do not. How can this be fixed? And is there an easy way to synchronize the wheels of a car?

else if(obj.Code == PhotonEvents.WHEEL_UPDATE_EVENT)
        {
            object[] data = (object[])obj.CustomData;

            Vector3 pos = new Vector3((float)data[0], (float)data[1], (float)data[2]);
            Quaternion rot = Quaternion.Euler((float)data[3], (float)data[4], (float)data[5]);
            int ViewId = (int)data[6];
            int i = (int)data[7];
            bool isFront = (bool)data[8];
            

            foreach (var playerCar in raceManager.carObjects)
            {
                if (playerCar.GetComponent<CarController>() &&
                    playerCar.GetComponent<PhotonView>().ViewID == ViewId)
                {
                    var car = playerCar.GetComponent<CarController>();
                    if (isFront)
                    {
                        car.FrontWheelTrans*.position = pos;*

car.FrontWheelTrans*.rotation = rot;*
}
else
{
car.RearWheelTrans*.position = pos;*
car.RearWheelTrans*.rotation = rot;*
}
break;
}
}
}
Wheel update code from the local player
private void UpdateAllWheelPose()
{
UpdateWheelPose(FrontWheelsCol[0], FrontWheelTrans[0], 0, true);
UpdateWheelPose(FrontWheelsCol[1], FrontWheelTrans[1], 1, true);
UpdateWheelPose(RearWheelsCol[0], RearWheelTrans[0], 0, false);
UpdateWheelPose(RearWheelsCol[1], RearWheelTrans[1], 1, false);
UpdateWheelPose(RearWheelsCol[2], RearWheelTrans[2], 2, false);
UpdateWheelPose(RearWheelsCol[3], RearWheelTrans[3], 3, false);
}

private void UpdateWheelPose(WheelCollider wheelCollider, Transform wheelTransform, int i, bool isFront)
{
Vector3 pos = wheelTransform.position;
Quaternion rot = wheelTransform.rotation;
wheelCollider.GetWorldPose(out pos, out rot);
wheelTransform.position = pos;
wheelTransform.rotation = rot;

object[] data = { pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, photonView.ViewID, i, isFront };

PhotonNetwork.RaiseEvent(PhotonEvents.WHEEL_UPDATE_EVENT, data, RaiseEventOptions.Default,
SendOptions.SendUnreliable);
}

The short answer would be: “You don’t”.

To elaborate this statement: All the information you send over the network should be important information. Especially informations like speed, position, steering angle, user forward/backwards input for example. Imo sending the wheel rotation is a bad idea as this is just something cosmetic which does not have to be 100% identical and at the same time can simply be recalculated on the client. This saves 1) Bandwidth and might even result in an equally good visual. The user would never know the difference.

In case you are really keen on still doing this by sending the rotation: ofc your current solution is “jumpy”. You send a rotation every 0.1seconds and directly apply it at the moment. That is like watching a movie with 10 frames per second. What you have to do instead is to take the new value and strech the application of the new value over the next 0.1 seconds by using Lerp for example. This is the most basic problem solution you can take to smoothing out sync values.

There are lots of tutorials, blogs and questions to be found on the web for this.
E.g. check out this here, this might help you: Link to Blog