-
Notifications
You must be signed in to change notification settings - Fork 437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kinematic Rigidbody Interpolation bug only when using Netcode? #2765
Comments
Rigidbody should not have interpolation enabled if you are interpolating with NetworkTransform. |
@NoelStephensUnity But the problem occurs on the authoritative instance. NetworkTransform shouldn't be interpolating on the authoritative side? "Interpolation is enabled by default and is recommended if you desire smooth transitions between transform updates on non-authoritative instances." |
Well, I can definitely understand the confusion and I should have provided a bit more information to help clarify what is happening. With RPCs there are some timing/order of operations things to consider. The first place to look would be the NetworkManager.NetworkUpdate method. The thing to take note of is that incoming messages are processed during the EarlyUpdate portion of a frame. The Order of Execution for Event Functions page doesn't provide the whole picture in regards to all updates that occur in one frame, but is always a good thing to better understand when physics stuff is applied and that particular order of operations. Fortunately, if we look at the NetworkUpdateStage we can see how all of the pertinent stages are invoked during a single frame:
What I believe is happening is:
I believe this is why, when Rigidbody interpolation on the server side is enabled, you are seeing this "snap back" when a client invokes the Rpc. The reason it doesn't happen at all on the server side is that you are handling the dropping of the object during the component's Update (Update portion of a frame) which FixedUpdate has already occurred and any physics relative updates to the transform applied. If you want to keep the
The gist of this is that if you want to apply adjustments to a server authoritative Really, this needs to be outlined in the documentation and I just haven't had the time to add these kinds of details... but I am now putting this on my list of things to update 👍 Let me know if this makes sense and resolves your issue? |
As a side note, if you handle everything in local space...then you might not even need to teleport as long as you don't parent with WorldPositionStays set to true... whatever the offset is on the player holding the item will be the same local space offset if you parent with WorldPositionStays set to false... so you could have a pre-defined "desired target offset" on the CarriedTest and upon the parent being set you could interpolate (server side) towards the desired offset until it reaches a "close to approximation" of the desired offset. This "should" make it look like the object is being "set down". |
@NoelStephensUnity Excited to dive into this on Monday! Have a great weekend. |
@NoelStephensUnity Ok, I read your much appreciated response and yes this is pretty much what I expected as the source of the problem. Your proposed fix does work. It'll be interesting to see how much we have to use that pattern in our game... I'm genuinely curious how often the order of operations will be a problem. I've still got one place where it seems like this same flavor of problem is happening, but it is much less consistent. Any clever ideas to boost the chances of this timing issue occurring so I can convince myself I've actually fixed it? A big change to the fixed timestep for testing purposes? |
Hmmm... yeah it depends upon what that code looks like and the things that could be impacted... Once you replicate the issue... you can then just add a "toggle" that you can set during runtime to have the same code that is being invoked during EarlyUpdate (i.e. simulating processing messages and applying values) to simply update some values and optionally apply the values during Update.
Something along those lines might help you artificially replicate the issue and verify by applying the values to the <insert whatever physics related values/components here> during Update vs EarlyUpate the issue does not occur. Again...sort of "winging it" since I don't have all of the details on that one place that could be hard to determine if it is fixed or not...but if I wanted to try and replicate an issue like this I would most likely start with implementing |
Thanks! |
Let me know if this resolved your issue (when you can for certain come to that conclusion). |
@NoelStephensUnity yes, I believe this is resolved. I didn't actually end up needing to try using INetworkUpdateSystem because our interface to our rigidbodies was wrapped in such a way that I should have fixed the issue globally now in our code base. |
So the biggest source of my problems with objects snapping back to old positions and driving me crazy is actually that the built-in networked re-parenting in NetworkObject is completely broken when you have any client authoritative positioning in your game: #2842 |
Side note: The distributed authority update includes some updates to Rigidbody stuff that allows for better NT <--> Rigidbody synchronization by allowing you to select whether you want the Rigidbody to control transform updates or not. This allows you to use Rigidbody interpolation on both the authoritative and non-authoritative instances and keeps better synchronization between the PhysX and Unity transforms. |
I'm seeing unexpected behavior from a kinematic Rigidbody when using Netcode that's sort of related to this Unity bug:
https://forum.unity.com/threads/interpolation-still-occurs-when-directly-setting-position-rotation-of-a-kinematic-rigidbody.1332504/
I'm using Unity 2022.3.10f1 and Netcode for Gameobject 1.6.0
If I destroy a kinematic Rigidbody (using
Object.Destroy
) while Interpolation is set to Interpolate, and then I useNetworkTransform.Teleport
to move the position of that Rigidbody, the object will snap back to its old Rigidbody position if the origin of theTeleport
call was a Server RPC called by a remote client.If the code is run by the host/server, the position doesn't snap back. If Interpolation is set to None on the Rigidbody before the Teleport, the position doesn't snap back.
Repro Use Case
I have a stationary cube:
And I have a moving sphere with a NetworkBehaviour (and no, it doesn't have a NetworkRigidbody):
CarriestTest.cs
Rarely, the bug won't happen (framerate dependency? I dunno?). But it seems like an almost 100% repro rate for me.
Perhaps this is Unity Rigidbody interpolation behaving as normal, and the issue that Netcode is introducing here is a race condition between whether the Teleport happens before or after the final interpolation? I dunno?
Personally, I think that setting the position on the Transform of a kinematic Rigidbody should teleport it and bypass Interpolation all the time.
The text was updated successfully, but these errors were encountered: