Skip to content

Commit 90cbb1e

Browse files
fix: ownership change halfprecision, session owner onclientconnected, and minor optimizations (#2948)
* fix Fixing issue when using half float precision and ownership changes, the current base position needs to be synchronized. * fix This fixes the issue of not invoking OnClientConnected when scene management is enabled for the session owner of a distributed authority session. * update Minor reduction in allocs while processing received messages (with the asteroids stress test this removes a regular 83kb allocation that occurs when processing received messages). * update Making a client's owned objects be returned as an array as opposed to a list for performance purposes. * update Adding change log entries. * update Adding the PR number to the changelog entries. * fix Cast the local variable so message hooks based on type still work. * style adding and removing whitespaces... * style removing using statement for generic collections. * style Fixing spelling of private dictionary. * update Moving around how distributed authority mode is checked. First pass of getting UnityTransport to be able to dictate what network topology is currently available (during a session). * update minor updates to NetworkTransform * update Only display the Start Client option in the inspector view when distributed authority mode is selected. * updte Adding event for when a session owner is promoted. * update adding a few more change log entries. * test fix Adding the same changes made to UnityTransport to MockTransport. * update Additional control flow for topology usage check * fix Fixing issue with NetworkObject ownership properties not showing up in the inspector view. Renaming the version define from MULTIPLAYER_SDK_INSTALLED to MULTIPLAYER_SERVICES_SDK_INSTALLED. Removing the components folder that was used for the assembly that no longer exists. * update Modifying the EveryoneRpcTarget so that it uses the NotAuthorityRpcTarget and AuthorityRpcTarget when in distributed authority mode. * update handling minor merge conflict * fix Fixing issue with motion based on very small linear velocity values. * update Adding 2D rigibody threshold calculations. Disabling the auto session owner promotion in distributed authority host mode. * fix and style Initializing NetworkManager dependent properties within the OnNetworkSpawn of the NetworkRigidbodyBase class. Removing whitespaces from NetworkConnectionManager. * update adding change log entries * fix declaring var rotationThreshold when there is no physics package installed. * update reverting previous change. Did another deep profile with Unity 6 (5f1) and this area does not seem to be causing any allocations. * update Adding authority mode selection drop down and exposing the NetworkTransformEditor OnEnable method (making it virtual) so the control can be derived from and extended. * update adding changelog entry for NetworkTransformEditor adjustment. * update make sure to update to Owner authority during initialization.
1 parent 60d321d commit 90cbb1e

23 files changed

+379
-91
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
66

77
Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).
88

9+
## [Unreleased]
10+
11+
### Added
12+
13+
- Added event `NetworkManager.OnSessionOwnerPromoted` that is invoked when a new session owner promotion occurs. (#2948)
14+
- Added `NetworkRigidBodyBase.GetLinearVelocity` and `NetworkRigidBodyBase.SetLinearVelocity` convenience/helper methods. (#2948)
15+
- Added `NetworkRigidBodyBase.GetAngularVelocity` and `NetworkRigidBodyBase.SetAngularVelocity` convenience/helper methods. (#2948)
16+
17+
### Fixed
18+
19+
- Fixed issue when `NetworkTransform` half float precision is enabled and ownership changes the current base position was not being synchronized. (#2948)
20+
- Fixed issue where `OnClientConnected` not being invoked on the session owner when connecting to a new distributed authority session. (#2948)
21+
- Fixed issue where Rigidbody micro-motion (i.e. relatively small velocities) would result in non-authority instances slightly stuttering as the body would come to a rest (i.e. no motion). Now, the threshold value can increase at higher velocities and can decrease slightly below the provided threshold to account for this. (#2948)
22+
23+
### Changed
24+
25+
- Changed the client's owned objects is now returned (`NetworkClient` and `NetworkSpawnManager`) as an array as opposed to a list for performance purposes. (#2948)
26+
- Changed `NetworkTransfrom.TryCommitTransformToServer` to be internal as it will be removed by the final 2.0.0 release. (#2948)
27+
- Changed `NetworkTransformEditor.OnEnable` to a virtual method to be able to customize a `NetworkTransform` derived class by creating a derived editor control from `NetworkTransformEditor`. (#2948)
28+
29+
930
## [2.0.0-exp.5] - 2024-06-03
1031

1132
### Added

com.unity.netcode.gameobjects/Components.meta

Lines changed: 0 additions & 8 deletions
This file was deleted.

com.unity.netcode.gameobjects/Editor/NetworkManagerEditor.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class NetworkManagerEditor : UnityEditor.Editor
3030
private SerializedProperty m_ProtocolVersionProperty;
3131
private SerializedProperty m_NetworkTransportProperty;
3232
private SerializedProperty m_TickRateProperty;
33-
#if MULTIPLAYER_SDK_INSTALLED
33+
#if MULTIPLAYER_SERVICES_SDK_INSTALLED
3434
private SerializedProperty m_NetworkTopologyProperty;
3535
#endif
3636
private SerializedProperty m_ClientConnectionBufferTimeoutProperty;
@@ -102,7 +102,7 @@ private void Initialize()
102102
m_ProtocolVersionProperty = m_NetworkConfigProperty.FindPropertyRelative("ProtocolVersion");
103103
m_NetworkTransportProperty = m_NetworkConfigProperty.FindPropertyRelative("NetworkTransport");
104104
m_TickRateProperty = m_NetworkConfigProperty.FindPropertyRelative("TickRate");
105-
#if MULTIPLAYER_SDK_INSTALLED
105+
#if MULTIPLAYER_SERVICES_SDK_INSTALLED
106106
m_NetworkTopologyProperty = m_NetworkConfigProperty.FindPropertyRelative("NetworkTopology");
107107
#endif
108108
m_ClientConnectionBufferTimeoutProperty = m_NetworkConfigProperty.FindPropertyRelative("ClientConnectionBufferTimeout");
@@ -142,7 +142,7 @@ private void CheckNullProperties()
142142
m_ProtocolVersionProperty = m_NetworkConfigProperty.FindPropertyRelative("ProtocolVersion");
143143
m_NetworkTransportProperty = m_NetworkConfigProperty.FindPropertyRelative("NetworkTransport");
144144
m_TickRateProperty = m_NetworkConfigProperty.FindPropertyRelative("TickRate");
145-
#if MULTIPLAYER_SDK_INSTALLED
145+
#if MULTIPLAYER_SERVICES_SDK_INSTALLED
146146
m_NetworkTopologyProperty = m_NetworkConfigProperty.FindPropertyRelative("NetworkTopology");
147147
#endif
148148
m_ClientConnectionBufferTimeoutProperty = m_NetworkConfigProperty.FindPropertyRelative("ClientConnectionBufferTimeout");
@@ -186,7 +186,7 @@ public override void OnInspectorGUI()
186186

187187
EditorGUILayout.Space();
188188
EditorGUILayout.LabelField("Network Settings", EditorStyles.boldLabel);
189-
#if MULTIPLAYER_SDK_INSTALLED
189+
#if MULTIPLAYER_SERVICES_SDK_INSTALLED
190190
EditorGUILayout.PropertyField(m_NetworkTopologyProperty);
191191
#endif
192192
EditorGUILayout.PropertyField(m_ProtocolVersionProperty);
@@ -310,21 +310,32 @@ public override void OnInspectorGUI()
310310
GUI.enabled = false;
311311
}
312312

313-
if (GUILayout.Button(new GUIContent("Start Host", "Starts a host instance" + buttonDisabledReasonSuffix)))
313+
if (m_NetworkManager.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer)
314314
{
315-
m_NetworkManager.StartHost();
316-
}
315+
if (GUILayout.Button(new GUIContent("Start Host", "Starts a host instance" + buttonDisabledReasonSuffix)))
316+
{
317+
m_NetworkManager.StartHost();
318+
}
317319

318-
if (GUILayout.Button(new GUIContent("Start Server", "Starts a server instance" + buttonDisabledReasonSuffix)))
319-
{
320-
m_NetworkManager.StartServer();
321-
}
320+
if (GUILayout.Button(new GUIContent("Start Server", "Starts a server instance" + buttonDisabledReasonSuffix)))
321+
{
322+
m_NetworkManager.StartServer();
323+
}
322324

323-
if (GUILayout.Button(new GUIContent("Start Client", "Starts a client instance" + buttonDisabledReasonSuffix)))
325+
if (GUILayout.Button(new GUIContent("Start Client", "Starts a client instance" + buttonDisabledReasonSuffix)))
326+
{
327+
m_NetworkManager.StartClient();
328+
}
329+
}
330+
else
324331
{
325-
m_NetworkManager.StartClient();
332+
if (GUILayout.Button(new GUIContent("Start Client", "Starts a distributed authority client instance" + buttonDisabledReasonSuffix)))
333+
{
334+
m_NetworkManager.StartClient();
335+
}
326336
}
327337

338+
328339
if (!EditorApplication.isPlaying)
329340
{
330341
GUI.enabled = true;

com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.Collections.Generic;
2-
#if MULTIPLAYER_SDK_INSTALLED
2+
#if BYPASS_DEFAULT_ENUM_DRAWER && MULTIPLAYER_SERVICES_SDK_INSTALLED
33
using System.Linq;
44
#endif
55
using UnityEditor;
@@ -148,7 +148,7 @@ private void OnDestroy()
148148

149149
// Keeping this here just in case, but it appears that in Unity 6 the visual bugs with
150150
// enum flags is resolved
151-
#if BYPASS_DEFAULT_ENUM_DRAWER && MULTIPLAYER_SDK_INSTALLED
151+
#if BYPASS_DEFAULT_ENUM_DRAWER && MULTIPLAYER_SERVICES_SDK_INSTALLED
152152
[CustomPropertyDrawer(typeof(NetworkObject.OwnershipStatus))]
153153
public class NetworkObjectOwnership : PropertyDrawer
154154
{

com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class NetworkTransformEditor : UnityEditor.Editor
3030
private SerializedProperty m_UseQuaternionCompression;
3131
private SerializedProperty m_UseHalfFloatPrecision;
3232
private SerializedProperty m_SlerpPosition;
33+
private SerializedProperty m_AuthorityMode;
3334

3435
private static int s_ToggleOffset = 45;
3536
private static float s_MaxRowWidth = EditorGUIUtility.labelWidth + EditorGUIUtility.fieldWidth + 5;
@@ -38,7 +39,7 @@ public class NetworkTransformEditor : UnityEditor.Editor
3839
private static GUIContent s_ScaleLabel = EditorGUIUtility.TrTextContent("Scale");
3940

4041
/// <inheritdoc/>
41-
public void OnEnable()
42+
public virtual void OnEnable()
4243
{
4344
m_UseUnreliableDeltas = serializedObject.FindProperty(nameof(NetworkTransform.UseUnreliableDeltas));
4445
m_SyncPositionXProperty = serializedObject.FindProperty(nameof(NetworkTransform.SyncPositionX));
@@ -59,12 +60,13 @@ public void OnEnable()
5960
m_UseQuaternionCompression = serializedObject.FindProperty(nameof(NetworkTransform.UseQuaternionCompression));
6061
m_UseHalfFloatPrecision = serializedObject.FindProperty(nameof(NetworkTransform.UseHalfFloatPrecision));
6162
m_SlerpPosition = serializedObject.FindProperty(nameof(NetworkTransform.SlerpPosition));
63+
m_AuthorityMode = serializedObject.FindProperty(nameof(NetworkTransform.AuthorityMode));
6264
}
6365

6466
/// <inheritdoc/>
6567
public override void OnInspectorGUI()
6668
{
67-
EditorGUILayout.LabelField("Syncing", EditorStyles.boldLabel);
69+
EditorGUILayout.LabelField("Axis to Synchronize", EditorStyles.boldLabel);
6870
{
6971
GUILayout.BeginHorizontal();
7072

@@ -126,6 +128,11 @@ public override void OnInspectorGUI()
126128
GUILayout.EndHorizontal();
127129
}
128130

131+
EditorGUILayout.Space();
132+
EditorGUILayout.LabelField("Authority", EditorStyles.boldLabel);
133+
{
134+
EditorGUILayout.PropertyField(m_AuthorityMode);
135+
}
129136
EditorGUILayout.Space();
130137
EditorGUILayout.LabelField("Thresholds", EditorStyles.boldLabel);
131138
EditorGUILayout.PropertyField(m_PositionThresholdProperty);

com.unity.netcode.gameobjects/Editor/com.unity.netcode.editor.asmdef

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
{
5858
"name": "com.unity.services.multiplayer",
5959
"expression": "0.2.0",
60-
"define": "MULTIPLAYER_SDK_INSTALLED"
60+
"define": "MULTIPLAYER_SERVICES_SDK_INSTALLED"
6161
}
6262
],
6363
"noEngineReferences": false

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

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public abstract class NetworkRigidbodyBase : NetworkBehaviour
4545
private Rigidbody m_Rigidbody;
4646
private Rigidbody2D m_Rigidbody2D;
4747
internal NetworkTransform NetworkTransform;
48+
private float m_TickFrequency;
49+
private float m_TickRate;
50+
4851
private enum InterpolationTypes
4952
{
5053
None,
@@ -120,6 +123,129 @@ protected void Initialize(RigidbodyTypes rigidbodyType, NetworkTransform network
120123
}
121124
}
122125

126+
internal Vector3 GetAdjustedPositionThreshold()
127+
{
128+
// Since the threshold is a measurement of unity world space units per tick, we will allow for the maximum threshold
129+
// to be no greater than the threshold measured in unity world space units per second
130+
var thresholdMax = NetworkTransform.PositionThreshold * m_TickRate;
131+
// Get the velocity in unity world space units per tick
132+
var perTickVelocity = GetLinearVelocity() * m_TickFrequency;
133+
// Since a rigid body can have "micro-motion" when allowed to come to rest (based on friction etc), we will allow for
134+
// no less than 1/10th the threshold value.
135+
var minThreshold = NetworkTransform.PositionThreshold * 0.1f;
136+
137+
// Finally, we adjust the threshold based on the body's current velocity
138+
perTickVelocity.x = Mathf.Clamp(Mathf.Abs(perTickVelocity.x), minThreshold, thresholdMax);
139+
perTickVelocity.y = Mathf.Clamp(Mathf.Abs(perTickVelocity.y), minThreshold, thresholdMax);
140+
// 2D Rigidbody only moves on x & y axis
141+
if (!m_IsRigidbody2D)
142+
{
143+
perTickVelocity.z = Mathf.Clamp(Mathf.Abs(perTickVelocity.z), minThreshold, thresholdMax);
144+
}
145+
146+
return perTickVelocity;
147+
}
148+
149+
internal Vector3 GetAdjustedRotationThreshold()
150+
{
151+
// Since the rotation threshold is a measurement pf degrees per tick, we get the maximum threshold
152+
// by calculating the threshold in degrees per second.
153+
var thresholdMax = NetworkTransform.RotAngleThreshold * m_TickRate;
154+
// Angular velocity is expressed in radians per second where as the rotation being checked is in degrees.
155+
// Convert the angular velocity to degrees per second and then convert that to degrees per tick.
156+
var rotationPerTick = (GetAngularVelocity() * Mathf.Rad2Deg) * m_TickFrequency;
157+
var minThreshold = NetworkTransform.RotAngleThreshold * m_TickFrequency;
158+
159+
// 2D Rigidbody only rotates around Z axis
160+
if (!m_IsRigidbody2D)
161+
{
162+
rotationPerTick.x = Mathf.Clamp(Mathf.Abs(rotationPerTick.x), minThreshold, thresholdMax);
163+
rotationPerTick.y = Mathf.Clamp(Mathf.Abs(rotationPerTick.y), minThreshold, thresholdMax);
164+
}
165+
rotationPerTick.z = Mathf.Clamp(Mathf.Abs(rotationPerTick.z), minThreshold, thresholdMax);
166+
167+
return rotationPerTick;
168+
}
169+
170+
/// <summary>
171+
/// Sets the linear velocity of the Rigidbody.
172+
/// </summary>
173+
/// <remarks>
174+
/// For <see cref="Rigidbody2D"/>, only the x and y components of the <see cref="Vector3"/> are applied.
175+
/// </remarks>
176+
public void SetLinearVelocity(Vector3 linearVelocity)
177+
{
178+
if (m_IsRigidbody2D)
179+
{
180+
m_Rigidbody2D.velocity = linearVelocity;
181+
}
182+
else
183+
{
184+
m_Rigidbody.linearVelocity = linearVelocity;
185+
}
186+
}
187+
188+
/// <summary>
189+
/// Gets the linear velocity of the Rigidbody.
190+
/// </summary>
191+
/// <remarks>
192+
/// For <see cref="Rigidbody2D"/>, the <see cref="Vector3"/> velocity returned is only applied to the x and y components.
193+
/// </remarks>
194+
/// <returns><see cref="Vector3"/> as the linear velocity</returns>
195+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
196+
public Vector3 GetLinearVelocity()
197+
{
198+
if (m_IsRigidbody2D)
199+
{
200+
return m_Rigidbody2D.velocity;
201+
}
202+
else
203+
{
204+
return m_Rigidbody.linearVelocity;
205+
}
206+
}
207+
208+
/// <summary>
209+
/// Sets the angular velocity for the Rigidbody.
210+
/// </summary>
211+
/// <remarks>
212+
/// For <see cref="Rigidbody2D"/>, the z component of <param name="angularVelocity"/> is only used to set the angular velocity.
213+
/// A quick way to pass in a 2D angular velocity component is: <see cref="Vector3.forward"/> * angularVelocity (where angularVelocity is a float)
214+
/// </remarks>
215+
/// <param name="angularVelocity">the angular velocity to apply to the body</param>
216+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
217+
public void SetAngularVelocity(Vector3 angularVelocity)
218+
{
219+
if (m_IsRigidbody2D)
220+
{
221+
m_Rigidbody2D.angularVelocity = angularVelocity.z;
222+
}
223+
else
224+
{
225+
m_Rigidbody.angularVelocity = angularVelocity;
226+
}
227+
}
228+
229+
/// <summary>
230+
/// Gets the angular velocity for the Rigidbody.
231+
/// </summary>
232+
/// <remarks>
233+
/// For <see cref="Rigidbody2D"/>, the z component of the <see cref="Vector3"/> returned is the angular velocity of the object.
234+
/// </remarks>
235+
/// <returns>angular velocity as a <see cref="Vector3"/></returns>
236+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
237+
public Vector3 GetAngularVelocity()
238+
{
239+
if (m_IsRigidbody2D)
240+
{
241+
return Vector3.forward * m_Rigidbody2D.velocity;
242+
}
243+
else
244+
{
245+
return m_Rigidbody.angularVelocity;
246+
}
247+
}
248+
123249
/// <summary>
124250
/// Gets the position of the Rigidbody
125251
/// </summary>
@@ -501,6 +627,8 @@ internal void UpdateOwnershipAuthority()
501627
/// <inheritdoc />
502628
public override void OnNetworkSpawn()
503629
{
630+
m_TickFrequency = 1.0f / NetworkManager.NetworkConfig.TickRate;
631+
m_TickRate = NetworkManager.NetworkConfig.TickRate;
504632
UpdateOwnershipAuthority();
505633
}
506634

0 commit comments

Comments
 (0)