diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 127203e7d3..5c66fc5668 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -24,6 +24,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Fixed `NetworkTransform` issue where a user could enable UseUnreliableDeltas while SwitchTransformSpaceWhenParented was also enabled (and vice versa). (#3875) - Fixed issue where `NetworkManager` was not cleaning itself up if an exception was thrown while starting. (#3864) - Prevented a `NullReferenceException` in `UnityTransport` when using a custom `INetworkStreamDriverConstructor` that doesn't use all the default pipelines and the multiplayer tools package is installed. (#3853) diff --git a/com.unity.netcode.gameobjects/Documentation~/components/helper/networktransform.md b/com.unity.netcode.gameobjects/Documentation~/components/helper/networktransform.md index b0bca748fe..aeccc960a7 100644 --- a/com.unity.netcode.gameobjects/Documentation~/components/helper/networktransform.md +++ b/com.unity.netcode.gameobjects/Documentation~/components/helper/networktransform.md @@ -75,6 +75,9 @@ The following NetworkTransform properties can cause a full state update when cha - __Use Quaternion Compression__ - __Use Half Float Precision__ +> [!NOTE] +> **UseUnreliableDeltas** cannot be enabled if **SwitchTransformSpaceWhenParented** is enabled since **SwitchTransformSpaceWhenParented** requires deltas to be sent reliably. + ### Axis to Synchronize ![image](../../images/networktransform/AxisToSynchronize.png) @@ -180,6 +183,7 @@ To resolve this issue, you can enable the __Switch Transform Space When Parented Things to consider when using __Switch Transform Space When Parented__: - This property is synchronized by the authority instance. If you disable it on the authority instance then it will synchronize this adjustment on all non-authority instances. +- This property cannot be enabled when **UseUnreliableDeltas** is enabled as it requires deltas to be sent reliably. - When using __Switch Transform Space When Parented__, it's best to not make adjustments to the __NetworkTransform.InLocalSpace__ field and let the NetworkTransform handle this for you. - While you can still change __In Local Space__ directly via script while __Switch Transform Space When Parented__ is enabled, this could impact the end results. It is recommended to not adjust __In Local Space__ when __Switch Transform Space When Parented__ is enabled. diff --git a/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs b/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs index 62d565e753..31f3314bea 100644 --- a/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs +++ b/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs @@ -184,13 +184,45 @@ private void DisplayNetworkTransformProperties() EditorGUILayout.Space(); EditorGUILayout.LabelField("Delivery", EditorStyles.boldLabel); EditorGUILayout.PropertyField(m_TickSyncChildren); - EditorGUILayout.PropertyField(m_UseUnreliableDeltas); + // If both are set from a previous configuration, then SwitchTransformSpaceWhenParented takes + // precedence. + if (networkTransform.UseUnreliableDeltas && networkTransform.SwitchTransformSpaceWhenParented) + { + networkTransform.UseUnreliableDeltas = false; + } + GUI.enabled = !networkTransform.SwitchTransformSpaceWhenParented; + if (networkTransform.SwitchTransformSpaceWhenParented) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(m_UseUnreliableDeltas); + EditorGUILayout.LabelField($"Cannot use with {nameof(NetworkTransform.SwitchTransformSpaceWhenParented)}."); + EditorGUILayout.EndHorizontal(); + } + else + { + EditorGUILayout.PropertyField(m_UseUnreliableDeltas); + } + GUI.enabled = true; + EditorGUILayout.Space(); EditorGUILayout.LabelField("Configurations", EditorStyles.boldLabel); - EditorGUILayout.PropertyField(m_SwitchTransformSpaceWhenParented); + GUI.enabled = !networkTransform.UseUnreliableDeltas; + if (networkTransform.UseUnreliableDeltas) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(m_SwitchTransformSpaceWhenParented); + EditorGUILayout.LabelField($"Cannot use with {nameof(NetworkTransform.UseUnreliableDeltas)}."); + EditorGUILayout.EndHorizontal(); + } + else + { + EditorGUILayout.PropertyField(m_SwitchTransformSpaceWhenParented); + } + GUI.enabled = true; if (m_SwitchTransformSpaceWhenParented.boolValue) { m_TickSyncChildren.boolValue = true; + networkTransform.UseUnreliableDeltas = false; } else { diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index 15109c93db..64e9bc0b95 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -1370,6 +1370,7 @@ public enum AuthorityModes /// are sent using a reliable fragmented sequenced network delivery. /// /// + /// Cannot be used when is enabled.
/// The following more critical state updates are still sent as reliable fragmented sequenced:
/// /// The initial synchronization state update. @@ -1570,6 +1571,7 @@ internal bool SynchronizeScale /// When de-parented: Automatically transitions into world space and coverts any pending interpolation states to the relative local space on non-authority instances.
/// /// + /// Cannot be used if is enabled.
/// Only works with components that are not paired with a or component that is configured to use the rigid body for motion.
/// will automatically be set when this is enabled. /// This field is auto-synchronized with non-authority clients when changed by the authority instance. @@ -1958,6 +1960,28 @@ private void TryCommitTransform(bool synchronize = false, bool settingState = fa m_UseRigidbodyForMotion = m_NetworkRigidbodyInternal.UseRigidBodyForMotion; } #endif + // Authority check to assure that UseUnreliableDeltas is not set during runtime while using SwitchTransformSpaceWhenParented. + if (SwitchTransformSpaceWhenParented && UseUnreliableDeltas) + { + // If we didn't have UseUnreliableDeltas previously set... + if (!m_LocalAuthoritativeNetworkState.FlagStates.UnreliableFrameSync) + { + if (m_CachedNetworkManager.LogLevel <= LogLevel.Normal) + { + NetworkLog.LogWarning($"[{nameof(NetworkTransform)}][{name}] Reverting {nameof(UseUnreliableDeltas)} back to false as it cannot be enabled while {nameof(SwitchTransformSpaceWhenParented)} is enabled!"); + } + UseUnreliableDeltas = false; + } + else // Otherwise SwitchTransformSpaceWhenParented has changed while UseUnreliableDeltas was already set. + { + if (m_CachedNetworkManager.LogLevel <= LogLevel.Normal) + { + NetworkLog.LogWarning($"[{nameof(NetworkTransform)}][{name}] Reverting {nameof(SwitchTransformSpaceWhenParented)} back to false as it cannot be enabled while {nameof(UseUnreliableDeltas)} is enabled!"); + } + SwitchTransformSpaceWhenParented = false; + } + } + // If the transform has deltas (returns dirty) or if an explicitly set state is pending if (m_LocalAuthoritativeNetworkState.ExplicitSet || CheckForStateChange(ref m_LocalAuthoritativeNetworkState, synchronize, forceState: settingState)) {