I am having problems synchronizing the position and rotation of the car wheels in a server authoritative model.
Position and rotation of the car body (the one that has CoherenceSync component) are synchronizing well, however the wheels stay static all the time. I’ve tried selecting parent checkboxes, but nothing works.
I am using a simulation server to handle the movement of the car. Here you can see the code I use to send the input.
If you want to sync properties on a child-object you need to double click the prefab to go into prefab editing mode. From there you can select the child-object in the hierarchy, and its properties (including position and rotation) will be available to sync.
Yes, they are physics based. We use an external asset for this (VPP) but at the end it relies on Unity’s Wheel Collider.
The Rigidbody (attached to the Root of the Car) is not marked as Kinematic, since we want to have collisions with other cars with a realistic physics response.
Besides that, If I marked the Rigidbody as Kinematic, since we use a Server authoritative model, the local player’s car won’t move due to the fact that in this approach local instance do not have state authority, therefore is relaying on Input Authority to send/receive input to/from the simulation server.
Hmm, it’s a bit of a complex setup, hard to debug via forum… Please bear with me if I misunderstood something.
The way I understand it, the SimpleVehicleControllerInput is running on the client-side to send input to the server. This is correct.
Then SimpleVehicleController is hoping to run on both Client (when it has InputAuthority) and Server (who has StateAuthority). Is this correct?
If that is true, I see a conflict and potentially the root cause of your issue.
Exactly like no more than one actor on the network can have State authority on a network entity at a certain time, the same your scripts should act: only one “controlling” script should be trying to modify object state, and all others should follow (sync). That’s why we have the mechanism of auto-disabling scripts and/or setting RBs as kinematic when the entity becomes remote.
If you don’t set the RB as kinematic and keep the script active on the Client, the Client will be fighting the server: Client says the wheel is in position X and rotation Y, server has a different opinion… who wins?
Most probably you’ll have a lot of glitching, Client sets a position each FixedUpdate, but then every now and then Server comes and sets another one, local physic checks get wonky, etc.
So in general, any script hoping to modify synced properties should be off on the Client, and only run Server-side. Obviously a script could be still active if it’s doing something else, but if it’s affecting those properties, it’s most probably going to cause trouble.
Let me know if it’s the case, before I guess any further
Your assumptions are correct.
In fact I tried what you propose and “it works”. So big kudos for you!
Basically what I did is disable the SimpleVehicleController script for the networked entities, and make the RB Kinematic.
Now the wheels are synchronizing, but (surprise, surprise) with a weird rotation happening for both local and networked entities. This is a problem I was facing when playing around with a none server authoritative approach.
Now to solve the other issue. What could it be…
I think I asked this already on Discord, but: I know you sync the rotation of the root object (the car itself) and of the wheels. Do you also sync the rotations of all the intermediate GameObjects? (i.e. parents of the wheels)
Yes, I’ve double checked that, and all scripts are disabled for networked object.
One thing I noticed though is that the z-axis rotation on the wheels is being synchronized on the networked object (which is causing that flicker effect) even though it’s never changed on the local instance; only x and y rotation are changed.
I think what led me to realise it was the fact - and I had seen this in a previous video of yours) that the wheels would go crazy when going fast, but not when going slow.
Seems like if you have a rotation of like, 10, 20, 30 degrees in between 2 interpolated frames, then the interpolation will guess the right direction… but if the wheel is spinning fast, say 200 degrees rotation between two updates, when interpolated it might sometimes go in the wrong direction. That’s what I’m thinking.
So I don’t know… maybe you need a custom interpolation where if the perceived angle difference is too high, interpolation is interrupted? Or maybe it’s faked, like, the wheel keeps track of the rotation on one particular axis and rotates on that axis by a value that can only ever go up and down by slight amounts, never completely 180º around in one frame.
You could also try just making a new preset from the Configure window, and tweak its values.