Skip to content

Commit ee8c8ee

Browse files
fix: Auto configure rigidbody based on physics mode selection (#4229)
* fix Fixing issue with rigidbody and physics mode. * update Adding minor blurb about the rigidbody adjustments * style Adding whitespace * fix: scope physics mode workarounds to hybrid sessions and keep them across authority changes - AlwaysRun interpolation override now applies only when the session has hybrid prefabs (N4E defaults to AlwaysRun, so plain NGO sessions were affected), only to 3D Rigidbodies, and is reapplied on every kinematic/ownership update instead of being reset to the authored value. - Restores the authored kinematic capture for hybrid prefabs to Awake only, so OnDestroy no longer restores the runtime kinematic state. - Guards both NetcodeConfig.Global reads against a missing config, and compiles the full tick smoothing change only when a physics module is present.
1 parent 699cb27 commit ee8c8ee

3 files changed

Lines changed: 55 additions & 0 deletions

File tree

‎com.unity.netcode.gameobjects/Documentation~/ghostobjects.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ To convert a hybrid object back into a prefab that uses only one package, remove
8686
> [!NOTE]
8787
> Unity might prevent you from removing a **GhostObject** or **NetworkObject** component while the GameObject has `GhostBehaviour` or `NetworkBehaviour` components that depend on it. Remove the dependent components first.
8888
89+
## Mixed mode objects and physics
90+
91+
To avoid visual anomalies, NGO automatically adjusts some Rigidbody settings based on the **Physics Run Mode** of the `NetcodeConfig` asset:
92+
93+
- **Always Run**: In a session that has hybrid prefabs, non-hybrid NGO prefabs with a NetworkRigidbody and a 3D Rigidbody have the Rigidbody's **Interpolate** value set to **Extrapolate** on the authority instance and to **None** on all non-authority instances. The authority instance is the server or host for a server-authoritative NetworkTransform, or the owner for an owner-authoritative one. The value follows authority when ownership changes, and the original value is restored when the instance despawns.
94+
- **User Controlled**: Hybrid NGO prefabs with a NetworkRigidbody have **Full Tick Smoothing** set to **Disabled**.
95+
8996
## Additional resources
9097

9198
- [GhostObjects in Unity Netcode](https://docs.unity3d.com/Packages/com.unity.netcode@latest?subfolder=/manual/ghostobject/ghostobject.html)

‎com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,25 @@ private bool InitializeHybrid()
298298
return true;
299299
}
300300

301+
// Overrides the authored interpolation while spawned when the NetcodeConfig physics mode requires it.
302+
private bool m_UsePhysicsModeInterpolation;
303+
304+
/// <summary>
305+
/// Prevents the jitter an interpolated Rigidbody that is not a GhostObject shows in a hybrid session with <see cref="PhysicGroupRunMode.AlwaysRun"/>.
306+
/// </summary>
307+
private void SetPhysicsModeInterpolation()
308+
{
309+
var netcodeConfig = NetcodeConfig.Global;
310+
m_UsePhysicsModeInterpolation = !m_IsRigidbody2D && m_LocalNetworkManager.NetworkConfig.Prefabs.HasGhostPrefabs
311+
&& netcodeConfig != null && netcodeConfig.PhysicsRunMode == PhysicGroupRunMode.AlwaysRun;
312+
}
313+
314+
// The authority extrapolates and every other peer does not interpolate.
315+
private void ApplyPhysicsModeInterpolation()
316+
{
317+
SetInterpolation(m_IsAuthority ? InterpolationTypes.Extrapolate : InterpolationTypes.None);
318+
}
319+
301320
/// <summary>
302321
/// Kinematic on every peer except the server. Called at spawn because an in-scene placed instance has no session during Awake.
303322
/// </summary>
@@ -956,6 +975,14 @@ private void PostSetIsKinematic()
956975
return;
957976
}
958977

978+
#if UNIFIED_NETCODE
979+
if (m_UsePhysicsModeInterpolation)
980+
{
981+
ApplyPhysicsModeInterpolation();
982+
return;
983+
}
984+
#endif
985+
959986
if (UseRigidBodyForMotion)
960987
{
961988
// Exit early if the original interpolation type is not set to extrapolate or NetworkTransform interpolate is disabled
@@ -1103,6 +1130,12 @@ internal void UpdateOwnershipAuthority()
11031130
{
11041131
SetIsKinematic(!m_IsAuthority);
11051132
}
1133+
#if UNIFIED_NETCODE
1134+
else if (m_UsePhysicsModeInterpolation)
1135+
{
1136+
ApplyPhysicsModeInterpolation();
1137+
}
1138+
#endif
11061139
}
11071140

11081141
internal override void InternalOnNetworkPreSpawn(ref NetworkManager networkManager)
@@ -1122,6 +1155,9 @@ public override void OnNetworkSpawn()
11221155
#endif
11231156
m_TickFrequency = 1.0f / m_LocalNetworkManager.NetworkConfig.TickRate;
11241157
m_TickRate = m_LocalNetworkManager.NetworkConfig.TickRate;
1158+
#if UNIFIED_NETCODE
1159+
SetPhysicsModeInterpolation();
1160+
#endif
11251161
UpdateOwnershipAuthority();
11261162
}
11271163

‎com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefab.cs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,18 @@ public bool Validate(int index = -1)
179179
#if UNIFIED_NETCODE
180180
// Mark this network prefab as having to be registered via the unified API
181181
HasGhost = networkObject.HasGhost;
182+
183+
#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
184+
// With UserControlled physics, full tick smoothing holds a hybrid Rigidbody in place on the host.
185+
var netcodeConfig = NetcodeConfig.Global;
186+
if (HasGhost && netcodeConfig != null && netcodeConfig.PhysicsRunMode == PhysicGroupRunMode.UserControlled
187+
&& networkObject.GhostObject.FullTickSmoothing != FullTickSmoothingMode.Disabled
188+
&& networkObject.GetComponent<Components.NetworkRigidbodyBase>() != null)
189+
{
190+
NetworkLog.LogWarning(new Logging.Context(LogLevel.Developer, $"Disabling full tick smoothing on {networkObject.name} because the {nameof(NetcodeConfig)} physics mode is {PhysicGroupRunMode.UserControlled}.").AddNetworkObject(networkObject));
191+
networkObject.GhostObject.FullTickSmoothing = FullTickSmoothingMode.Disabled;
192+
}
193+
#endif
182194
#endif
183195
if (networkObject.InScenePlaced)
184196
{

0 commit comments

Comments
 (0)