Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ To convert a hybrid object back into a prefab that uses only one package, remove
> [!NOTE]
> 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.

## Mixed mode objects and physics

To avoid visual anomalies, NGO automatically adjusts some Rigidbody settings based on the **Physics Run Mode** of the `NetcodeConfig` asset:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To avoid visual anomalies, NGO automatically adjusts some Rigidbody settings based on the **Physics Run Mode** of the `NetcodeConfig` asset:
To avoid visual anomalies, Netcode for GameObjects automatically adjusts some Rigidbody settings based on the **Physics Run Mode** of the `NetcodeConfig` asset:


- **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.
- **User Controlled**: Hybrid NGO prefabs with a NetworkRigidbody have **Full Tick Smoothing** set to **Disabled**.
Comment on lines +93 to +94

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **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.
- **User Controlled**: Hybrid NGO prefabs with a NetworkRigidbody have **Full Tick Smoothing** set to **Disabled**.
- **Always Run**: In a session that has hybrid prefabs, non-hybrid Netcode for GameObjects 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.
- **User Controlled**: Hybrid Netcode for GameObjects prefabs with a NetworkRigidbody have **Full Tick Smoothing** set to **Disabled**.


## Additional resources

- [GhostObjects in Unity Netcode](https://docs.unity3d.com/Packages/com.unity.netcode@latest?subfolder=/manual/ghostobject/ghostobject.html)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,25 @@
return true;
}

// Overrides the authored interpolation while spawned when the NetcodeConfig physics mode requires it.
private bool m_UsePhysicsModeInterpolation;

/// <summary>
/// Prevents the jitter an interpolated Rigidbody that is not a GhostObject shows in a hybrid session with <see cref="PhysicGroupRunMode.AlwaysRun"/>.
/// </summary>
private void SetPhysicsModeInterpolation()
{
var netcodeConfig = NetcodeConfig.Global;
m_UsePhysicsModeInterpolation = !m_IsRigidbody2D && m_LocalNetworkManager.NetworkConfig.Prefabs.HasGhostPrefabs
&& netcodeConfig != null && netcodeConfig.PhysicsRunMode == PhysicGroupRunMode.AlwaysRun;
}

// The authority extrapolates and every other peer does not interpolate.
private void ApplyPhysicsModeInterpolation()
{
SetInterpolation(m_IsAuthority ? InterpolationTypes.Extrapolate : InterpolationTypes.None);
}

Check warning on line 318 in com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs#L316-L318

Added lines #L316 - L318 were not covered by tests

/// <summary>
/// Kinematic on every peer except the server. Called at spawn because an in-scene placed instance has no session during Awake.
/// </summary>
Expand Down Expand Up @@ -956,6 +975,14 @@
return;
}

#if UNIFIED_NETCODE
if (m_UsePhysicsModeInterpolation)
{
ApplyPhysicsModeInterpolation();
return;

Check warning on line 982 in com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs#L980-L982

Added lines #L980 - L982 were not covered by tests
}
#endif

if (UseRigidBodyForMotion)
{
// Exit early if the original interpolation type is not set to extrapolate or NetworkTransform interpolate is disabled
Expand Down Expand Up @@ -1103,6 +1130,12 @@
{
SetIsKinematic(!m_IsAuthority);
}
#if UNIFIED_NETCODE
else if (m_UsePhysicsModeInterpolation)
{
ApplyPhysicsModeInterpolation();
}

Check warning on line 1137 in com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

com.unity.netcode.gameobjects/Runtime/Components/NetworkRigidBodyBase.cs#L1134-L1137

Added lines #L1134 - L1137 were not covered by tests
#endif
}

internal override void InternalOnNetworkPreSpawn(ref NetworkManager networkManager)
Expand All @@ -1122,6 +1155,9 @@
#endif
m_TickFrequency = 1.0f / m_LocalNetworkManager.NetworkConfig.TickRate;
m_TickRate = m_LocalNetworkManager.NetworkConfig.TickRate;
#if UNIFIED_NETCODE
SetPhysicsModeInterpolation();
#endif
UpdateOwnershipAuthority();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@
#if UNIFIED_NETCODE
// Mark this network prefab as having to be registered via the unified API
HasGhost = networkObject.HasGhost;

#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
// With UserControlled physics, full tick smoothing holds a hybrid Rigidbody in place on the host.
var netcodeConfig = NetcodeConfig.Global;
if (HasGhost && netcodeConfig != null && netcodeConfig.PhysicsRunMode == PhysicGroupRunMode.UserControlled
&& networkObject.GhostObject.FullTickSmoothing != FullTickSmoothingMode.Disabled
&& networkObject.GetComponent<Components.NetworkRigidbodyBase>() != null)
{
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));
networkObject.GhostObject.FullTickSmoothing = FullTickSmoothingMode.Disabled;
}

Check warning on line 192 in com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefab.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefab.cs#L189-L192

Added lines #L189 - L192 were not covered by tests
#endif
#endif
if (networkObject.InScenePlaced)
{
Expand Down
Loading