Skip to content

Commit 2151772

Browse files
fix: NetworkRigidbody authority and ownership detection (#1891)
* fix MTT-3374 Initial changes for this fix. * fix Migrating the authority mode check to NetworkTransform since this is what dictates authority anyways. * style updated and added comments * test Adding ownership tests * update Realized we could further simplify NetworkRigidbody and added additional testing against owners not being Kinematic and non-owners being kinematic. Also had to have the NetworkManager relative test prefab instances ignore each others' colliders so they wouldn't skew the position testing. * style whitespace fixes * style parameter name change * style better clarity in a comment * update This fixes an issue with not being able to find ClientNetworkTransform and makes the IsServerAuhtoritative internal. * update realized we don't need to save the original Kinematic state. updated a comment * update needed to add COM_UNITY_MODULES_PHYSICS define in runtime and exclude the test if the physics module is not included. * style removing 2 CR/LF * update didn't need all of the changes made to the asmdef file * style removing xml doc API reference * Update com.unity.netcode.gameobjects/Tests/Runtime/com.unity.netcode.runtimetests.asmdef Co-authored-by: Fatih Mar <mfatihmar@gmail.com> * Update com.unity.netcode.runtimetests.asmdef * fix Had to adjust the rigid body interpolation setting to be based on authority and not NetworkTransform.Interpolate (bug from this PR) Had to re-adjust the original rigid body test to match the NetworkRigidbody change where when it is despawned physics is not applied. * fix Fixing edge case scenario with object parenting test. Co-authored-by: Fatih Mar <mfatihmar@gmail.com>
1 parent bd9fbca commit 2151772

File tree

8 files changed

+404
-66
lines changed

8 files changed

+404
-66
lines changed

com.unity.netcode.gameobjects/Components/NetworkRigidbody.cs

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,77 +5,97 @@ namespace Unity.Netcode.Components
55
{
66
/// <summary>
77
/// NetworkRigidbody allows for the use of <see cref="Rigidbody"/> on network objects. By controlling the kinematic
8-
/// mode of the rigidbody and disabling it on all peers but the authoritative one.
8+
/// mode of the <see cref="Rigidbody"/> and disabling it on all peers but the authoritative one.
99
/// </summary>
1010
[RequireComponent(typeof(Rigidbody))]
1111
[RequireComponent(typeof(NetworkTransform))]
1212
public class NetworkRigidbody : NetworkBehaviour
1313
{
14+
/// <summary>
15+
/// Determines if we are server (true) or owner (false) authoritative
16+
/// </summary>
17+
private bool m_IsServerAuthoritative;
18+
1419
private Rigidbody m_Rigidbody;
1520
private NetworkTransform m_NetworkTransform;
16-
17-
private bool m_OriginalKinematic;
1821
private RigidbodyInterpolation m_OriginalInterpolation;
1922

20-
// Used to cache the authority state of this rigidbody during the last frame
23+
// Used to cache the authority state of this Rigidbody during the last frame
2124
private bool m_IsAuthority;
2225

23-
/// <summary>
24-
/// Gets a bool value indicating whether this <see cref="NetworkRigidbody"/> on this peer currently holds authority.
25-
/// </summary>
26-
private bool HasAuthority => m_NetworkTransform.CanCommitToTransform;
27-
2826
private void Awake()
2927
{
30-
m_Rigidbody = GetComponent<Rigidbody>();
3128
m_NetworkTransform = GetComponent<NetworkTransform>();
29+
m_IsServerAuthoritative = m_NetworkTransform.IsServerAuthoritative();
30+
31+
m_Rigidbody = GetComponent<Rigidbody>();
32+
m_OriginalInterpolation = m_Rigidbody.interpolation;
33+
34+
// Set interpolation to none if NetworkTransform is handling interpolation, otherwise it sets it to the original value
35+
m_Rigidbody.interpolation = m_NetworkTransform.Interpolate ? RigidbodyInterpolation.None : m_OriginalInterpolation;
36+
37+
// Turn off physics for the rigid body until spawned, otherwise
38+
// clients can run fixed update before the first full
39+
// NetworkTransform update
40+
m_Rigidbody.isKinematic = true;
41+
}
42+
43+
/// <summary>
44+
/// For owner authoritative (i.e. ClientNetworkTransform)
45+
/// we adjust our authority when we gain ownership
46+
/// </summary>
47+
public override void OnGainedOwnership()
48+
{
49+
UpdateOwnershipAuthority();
3250
}
3351

34-
private void FixedUpdate()
52+
/// <summary>
53+
/// For owner authoritative(i.e. ClientNetworkTransform)
54+
/// we adjust our authority when we have lost ownership
55+
/// </summary>
56+
public override void OnLostOwnership()
3557
{
36-
if (NetworkManager.IsListening)
37-
{
38-
if (HasAuthority != m_IsAuthority)
39-
{
40-
m_IsAuthority = HasAuthority;
41-
UpdateRigidbodyKinematicMode();
42-
}
43-
}
58+
UpdateOwnershipAuthority();
4459
}
4560

46-
// Puts the rigidbody in a kinematic non-interpolated mode on everyone but the server.
47-
private void UpdateRigidbodyKinematicMode()
61+
/// <summary>
62+
/// Sets the authority differently depending upon
63+
/// whether it is server or owner authoritative
64+
/// </summary>
65+
private void UpdateOwnershipAuthority()
4866
{
49-
if (m_IsAuthority == false)
67+
if (m_IsServerAuthoritative)
5068
{
51-
m_OriginalKinematic = m_Rigidbody.isKinematic;
52-
m_Rigidbody.isKinematic = true;
53-
54-
m_OriginalInterpolation = m_Rigidbody.interpolation;
55-
// Set interpolation to none, the NetworkTransform component interpolates the position of the object.
56-
m_Rigidbody.interpolation = RigidbodyInterpolation.None;
69+
m_IsAuthority = NetworkManager.IsServer;
5770
}
5871
else
5972
{
60-
// Resets the rigidbody back to it's non replication only state. Happens on shutdown and when authority is lost
61-
m_Rigidbody.isKinematic = m_OriginalKinematic;
62-
m_Rigidbody.interpolation = m_OriginalInterpolation;
73+
m_IsAuthority = IsOwner;
6374
}
75+
76+
// If you have authority then you are not kinematic
77+
m_Rigidbody.isKinematic = !m_IsAuthority;
78+
79+
// Set interpolation of the Rigidbody based on authority
80+
// With authority: let local transform handle interpolation
81+
// Without authority: let the NetworkTransform handle interpolation
82+
m_Rigidbody.interpolation = m_IsAuthority ? m_OriginalInterpolation : RigidbodyInterpolation.None;
6483
}
6584

6685
/// <inheritdoc />
6786
public override void OnNetworkSpawn()
6887
{
69-
m_IsAuthority = HasAuthority;
70-
m_OriginalKinematic = m_Rigidbody.isKinematic;
71-
m_OriginalInterpolation = m_Rigidbody.interpolation;
72-
UpdateRigidbodyKinematicMode();
88+
UpdateOwnershipAuthority();
7389
}
7490

7591
/// <inheritdoc />
7692
public override void OnNetworkDespawn()
7793
{
78-
UpdateRigidbodyKinematicMode();
94+
m_Rigidbody.interpolation = m_OriginalInterpolation;
95+
// Turn off physics for the rigid body until spawned, otherwise
96+
// non-owners can run fixed updates before the first full
97+
// NetworkTransform update and physics will be applied (i.e. gravity, etc)
98+
m_Rigidbody.isKinematic = true;
7999
}
80100
}
81101
}

com.unity.netcode.gameobjects/Components/NetworkTransform.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,5 +960,22 @@ public void Teleport(Vector3 newPosition, Quaternion newRotation, Vector3 newSca
960960
TryCommitValuesToServer(newPosition, newRotationEuler, newScale, m_CachedNetworkManager.LocalTime.Time);
961961
m_LocalAuthoritativeNetworkState.IsTeleportingNextFrame = false;
962962
}
963+
964+
/// <summary>
965+
/// Override this and return false to follow the owner authoritative
966+
/// Otherwise, it defaults to server authoritative
967+
/// </summary>
968+
protected virtual bool OnIsServerAuthoritatitive()
969+
{
970+
return true;
971+
}
972+
973+
/// <summary>
974+
/// Used by <see cref="NetworkRigidbody"/> to determines if this is server or owner authoritative.
975+
/// </summary>
976+
internal bool IsServerAuthoritative()
977+
{
978+
return OnIsServerAuthoritatitive();
979+
}
963980
}
964981
}

com.unity.netcode.gameobjects/Samples/ClientNetworkTransform/Scripts/ClientNetworkTransform.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,10 @@ protected override void Update()
3636
}
3737
}
3838
}
39+
40+
protected override bool OnIsServerAuthoritatitive()
41+
{
42+
return false;
43+
}
3944
}
4045
}

0 commit comments

Comments
 (0)