feat: quaternion synchronization, delta position, and NetworkTransform bandwidth optimizations#2388
Conversation
Converted the original delta position compressor over to use 10 bit precision. We lose 2 bytes of savings (like the adjustable precision version) but: Deltas cannot exceed +/- 128.0f (so 30x per second rate of change would be +/- 3840 unity space units per second) The decompressed value(s) fault tolerance is +/- 0.10f. (50% reduction in size is the best precision vs compression ratio we can get with this approach)
Added a manual test for long-duration testing of delta position compression with precision loss compensation.
Adding quaternion synchronization without compression or precision loss compensation. Some axis specific NetworkTransform integration tests fail due to the quaternion synchronizing all axis. These tests will be adjusted once everything else (for quaternion compression and precision loss compensation) is in place.
This fixes an issue with the NestedNetworkTransform test. The children NetworkTransforms were still using world space synchronization which caused issues when the scale changed. When that was corrected, it then exposed a bug in the delta position implementation where the predicted client position was not taking local space into consideration. Also making sure k_QuaternionSync is not cleared after updating on the authoritative side.
Removing the sphere collider from the NetworkTransformOwnershipTests because the test basically ignores collision with other players and collision is not a factor of this test. Since the spheres are effectively "doing nothing", it didn't make sense to try and add them when they weren't being used for anything and more importantly they were causing the client side to have skewed results when OwnerAuthoritativeTests was run under the HostStartsAsOwner pass.
Temporarily adding updates to various NetworkTransform tests to account for current changes. (primarily to run stand alone testrunner builds on consoles to verify current changes still work on them)
Several adjustments to tests that take the HalfVector3 into consideration as well as some debug hooks for testing purposes.
This update: - Increases the precision of HalfVector4 when using quaternions - Adds UseHalfFloatPrecision property that when enabled will synchronize in half float values as well as synchronize the change in status on the non-authoritative sides. - Includes some debug mode adjustments (TBD if we will keep all of this)
Slowly backing out some legacy changes and debug info from NetworkTransform Updating some of the NetworkTransform tests to more recent changes.
|
I am curious why these new types were added when Unity already has these types in the Unity Mathematics package? Like many things within NGO it seems that you just end up creating your own version of a thing? Why not just make the types in a package that is used all over the place support serialization? and furthermore are compatible with Engine Types when required? |
|
@wackoisgod |
|
That would be correct; I just think introducing another new type seems kind of wasteful and confusing to people because now they can use the Unity.Mathmatics package which converts to Unity Engine types where required but then now they may have to convert to these NGO types when they want to use them on the network. I just don't see a lot of value in creating another type. I think VectorT is not a great type either because while yes it can be limited to an unmanaged type its really only value is primitive number types but nothing stops someone from putting any sort of struct in the type. |
|
@wackoisgod Please always feel free to bring up anything you see that needs a second pass "re-think" as I highly value your insights into things of this very nature and the more eyes on things the better (imo). 👍 |
|
We already indirectly depend on |
|
@ThusSpokeNomad Very cool graph... |

This update provides users with optional bandwidth optimizations (at the cost of precision) of up to 50% reduction in bandwidth costs per
NetworkTransforminstances. It also includes several changes that address issues related to rotation and parentedNetworkTransforms through the enabling of quaternion synchronization.NetworkTransformAdditions and ChangesQuaternionSynchronization: Added the ability to synchronize by quaternions (full precision). Using quaternion synchronization is recommended for scenarios where multiple axis of rotation can change and the transform in question is within a parent-child hierarchy. When enabled, per axis rotation flags are no longer visible in the editor as the entire quaternion is synchronized when any change in rotation occurs.QuaternionCompression: Added the ability to compress quaternions (requiresQuaternionSynchronization to be enabled). Reduces the cost of quaternion synchronization down to 4 bytes at the cost of additional loss in precision (a bit less precise than half float precision).NetworkTransformuses delta position synchronization to assure any loss in precision is recovered/handled in the next state update.NetworkTransformStateto public.SynchronizeTransform, toNetworkObjectthat allows users to disable the automatic synchronization of the associated transform to reduce the total bandwidth cost of spawning and late joining client synchronization. This is particularly useful if theNetworkObjectis used more for management related tasks and has no spatial synchronization needs.Internal Companion Project: This project demonstrates the bandwidth cost/savings based on which properties are set, the average precision loss over time (editor console log required), and can be used to visual the latency between the authoritative and non-authoritative instances.
Fixes
MTT-5252
MTT-5082
Related GitHub Issues Resolved:
#2353
#2299
#1977
Changelog
Added
NetworkTransform.UseHalfFloatPrecisionproperty that, when enabled, will use half float values for position, rotation, and scale. This yields a 50% bandwidth savings a the cost of precision.NetworkTransform.UseQuaternionSynchronizationproperty that, when enabled, will synchronize the entire quaternion.NetworkTransform.UseQuaternionCompressionproperty that, when enabled, will use a smallest three implementation reducing a full quaternion synchronization update to the size of an unsigned integer.NetworkTransform.SlerpPositionproperty that, when enabled along with interpolation being enabled, will interpolate usingVector3.Slerp.BufferedLinearInterpolatorVector3that replaces the float version, is now used byNetworkTransform, and provides the ability to enable or disableSlerp.HalfVector3used for scale when half float precision is enabled.HalfVector4used for rotation when half float precision and quaternion synchronization is enabled.HalfVector3DeltaPositionused for position when half float precision is enabled. This handles loss in position precision by updating only the delta position as opposed to the full position.NetworkTransform.GetSpaceRelativePositionandNetworkTransform.GetSpaceRelativeRotationhelper methods to return the proper values depending upon whether local or world space.NetworkTransform.OnAuthorityPushTransformStatevirtual method that is invoked just prior to sending theNetworkTransformStateto non-authoritative instances. This provides users with the ability to obtain more precise delta values for prediction related calculations.NetworkTransform.OnNetworkTransformStateUpdatedvirtual method that is invoked just after the authoritativeNetworkTransformStateis applied. This provides users with the ability to obtain more precise delta values for prediction related calculations.NetworkTransform.OnInitializevirtual method that is invoked after theNetworkTransformhas been initialized or re-initialized when ownership changes. This provides for a way to make adjustments whenNetworkTransformis initialized (i.e. resetting client prediction etc.)NetworkObject.SynchronizeTransformproperty (default istrue) that provides users with another way to help with bandwidth optimizations where, when set to false, theNetworkObject's associated transform will not be included when spawning and/or synchronizing late joining players.Changed
NetworkTransformauthority handles delta checks on each new network tick and no longer consumes processing cycles checking for deltas for all frames in-between ticks.NetworkTransformStatestructure is now public and now has public methods that provide access to key properties of theNetworkTransformStatestructure.NetworkTransforminterpolation adjusts its interpolation "ticks ago" to be 2 ticks latent if it is owner authoritative and the instance is not the server or 1 tick latent if the instance is the server and/or is server authoritative.Fixed
NetworkTransform. Now using half precision or full quaternion synchronization will always update all axis.NetworkTransformwas not setting the teleport flag when theNetworkTransform.InLocalSpacevalue changed. This issue only impactedNetworkTransformwhen interpolation was enabled.Testing and Documentation