Skip to content

Commit 534f74e

Browse files
fix: selecting everything selects session owner only (#3305)
* fix This fixes the issue with setting flags on NetworkObjects and the default Everything/All flag causing session owner to be grouped with the rest of the flags. Now all will initially select all flags but the session owner but if the all flag is selected again it toggles to just the SessionOwner flag. This also assures that all root in-scene placed NetworkObjects have the Distributable or SessionOwner flag set (if neither then it defaults to Distributable). * fix Fixing some logic that would only skip over children if it was logging a message. * update adding changelog entries. * style adding API comments * style Adding one for "None". * update Cleaning up some of the script. * style adding comments
1 parent 9493824 commit 534f74e

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1313
### Fixed
1414

1515
- Fixed `OnClientConnectedCallback` passing incorrect `clientId` when scene management is disabled. (#3312)
16+
- Fixed issue where the `NetworkObject.Ownership` custom editor did not take the default "Everything" flag into consideration. (#3305)
1617
- Fixed DestroyObject flow on non-authority game clients. (#3291)
1718
- Fixed exception being thrown when a `GameObject` with an associated `NetworkTransform` is disabled. (#3243)
1819
- Fixed issue where the scene migration synchronization table was not cleaned up if the `GameObject` of a `NetworkObject` is destroyed before it should have been. (#3230)
@@ -25,6 +26,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
2526

2627
### Changed
2728

29+
- Changed root in-scene placed `NetworkObject` instances now will always have either the `Distributable` permission set unless the `SessionOwner` permission is set. (#3305)
2830
- Changed the `DestroyObject` message to reduce the serialized message size and remove the unnecessary message field. (#3304)
2931
- Changed the `NetworkTimeSystem.Sync` method to use half RTT to calculate the desired local time offset as opposed to the full RTT. (#3212)
3032

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

+33-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ namespace Unity.Netcode.Editor
1414
[CanEditMultipleObjects]
1515
public class NetworkObjectEditor : UnityEditor.Editor
1616
{
17+
private const NetworkObject.OwnershipStatus k_AllOwnershipFlags = NetworkObject.OwnershipStatus.RequestRequired | NetworkObject.OwnershipStatus.Transferable | NetworkObject.OwnershipStatus.Distributable;
18+
private const int k_SessionOwnerFlagAsInt = (int)NetworkObject.OwnershipStatus.SessionOwner;
19+
1720
private bool m_Initialized;
1821
private NetworkObject m_NetworkObject;
1922
private bool m_ShowObservers;
@@ -114,10 +117,38 @@ public override void OnInspectorGUI()
114117
{
115118
EditorGUI.BeginChangeCheck();
116119
serializedObject.UpdateIfRequiredOrScript();
120+
121+
// Get the current ownership property and precalculate values in order to handle
122+
// the exclusion or inclusion of "all" or just the session owner flags.
123+
var ownershipProperty = serializedObject.FindProperty(nameof(NetworkObject.Ownership));
124+
var previousOwnership = (NetworkObject.OwnershipStatus)ownershipProperty.intValue;
125+
var hadAll = previousOwnership == k_AllOwnershipFlags;
126+
var hadSessionOwner = ownershipProperty.intValue == k_SessionOwnerFlagAsInt;
127+
117128
DrawPropertiesExcluding(serializedObject, k_HiddenFields);
118-
if (m_NetworkObject.IsOwnershipSessionOwner)
129+
130+
// If the ownership flags were changed
131+
var currentOwnership = (NetworkObject.OwnershipStatus)ownershipProperty.intValue;
132+
if (currentOwnership != previousOwnership)
119133
{
120-
m_NetworkObject.Ownership = NetworkObject.OwnershipStatus.SessionOwner;
134+
// Determine if we need to handle setting or removing the session owner flag specifically
135+
// when a user selects the "All" enum flag value.
136+
var hasSessionOwner = currentOwnership.HasFlag(NetworkObject.OwnershipStatus.SessionOwner);
137+
if (hasSessionOwner)
138+
{
139+
if (ownershipProperty.intValue == -1 && !hadAll)
140+
{
141+
ownershipProperty.intValue = (int)k_AllOwnershipFlags;
142+
}
143+
else if ((hadAll && !hadSessionOwner) || (!hadAll && !hadSessionOwner))
144+
{
145+
ownershipProperty.intValue = k_SessionOwnerFlagAsInt;
146+
}
147+
else if (hadSessionOwner && hasSessionOwner)
148+
{
149+
ownershipProperty.intValue &= ~k_SessionOwnerFlagAsInt;
150+
}
151+
}
121152
}
122153
serializedObject.ApplyModifiedProperties();
123154
EditorGUI.EndChangeCheck();

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

+29
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,15 @@ private void CheckForInScenePlaced()
322322

323323
// Default scene migration synchronization to false for in-scene placed NetworkObjects
324324
SceneMigrationSynchronization = false;
325+
326+
// Root In-scene placed NetworkObjects have to either have the SessionOwner or Distributable permission flag set.
327+
if (transform.parent == null)
328+
{
329+
if (!Ownership.HasFlag(OwnershipStatus.SessionOwner) && !Ownership.HasFlag(OwnershipStatus.Distributable))
330+
{
331+
Ownership |= OwnershipStatus.Distributable;
332+
}
333+
}
325334
}
326335
}
327336
#endif // UNITY_EDITOR
@@ -493,16 +502,36 @@ public void DeferDespawn(int tickOffset, bool destroy = true)
493502
/// <see cref="Transferable"/>: When set, a non-owner can obtain ownership immediately (without requesting and as long as it is not locked).
494503
/// <see cref="RequestRequired"/>: When set, a non-owner must request ownership from the owner (will always get locked once ownership is transferred).
495504
/// <see cref="SessionOwner"/>: When set, only the current session owner may have ownership over this object.
505+
/// <see cref="All"/>: Used within the inspector view only. When selected it will set the Distributable, Transferable, and RequestRequired flags or if those flags are already set it will select the SessionOwner flag by itself.
496506
/// </summary>
497507
// Ranges from 1 to 8 bits
498508
[Flags]
499509
public enum OwnershipStatus
500510
{
511+
/// <summary>
512+
/// When set, this instance will have no permissions (i.e. cannot distribute, transfer, etc).
513+
/// </summary>
501514
None = 0,
515+
/// <summary>
516+
/// When set, this instance will be automatically redistributed when a client joins (if not locked or no request is pending) or leaves.
517+
/// </summary>
502518
Distributable = 1 << 0,
519+
/// <summary>
520+
/// When set, a non-owner can obtain ownership immediately (without requesting and as long as it is not locked).
521+
/// </summary>
503522
Transferable = 1 << 1,
523+
/// <summary>
524+
/// When set, a non-owner must request ownership from the owner (will always get locked once ownership is transferred).
525+
/// </summary>
504526
RequestRequired = 1 << 2,
527+
/// <summary>
528+
/// When set, only the current session owner may have ownership over this object.
529+
/// </summary>
505530
SessionOwner = 1 << 3,
531+
/// <summary>
532+
/// Used within the inspector view only. When selected it will set the Distributable, Transferable, and RequestRequired flags or if those flags are already set it will select the SessionOwner flag by itself.
533+
/// </summary>
534+
All = ~0,
506535
}
507536

508537
/// <summary>

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1967,9 +1967,12 @@ internal void DistributeNetworkObjects(ulong clientId)
19671967
{
19681968
continue;
19691969
}
1970-
if ((!child.IsOwnershipDistributable || !child.IsOwnershipTransferable) && NetworkManager.LogLevel == LogLevel.Developer)
1970+
if (!child.IsOwnershipDistributable || !child.IsOwnershipTransferable)
19711971
{
1972-
NetworkLog.LogWarning($"Sibling {child.name} of root parent {ownerList.Value[i].name} is neither transferrable or distributable! Object distribution skipped and could lead to a potentially un-owned or owner-mismatched {nameof(NetworkObject)}!");
1972+
if (NetworkManager.LogLevel == LogLevel.Developer)
1973+
{
1974+
NetworkLog.LogWarning($"Sibling {child.name} of root parent {ownerList.Value[i].name} is neither transferrable or distributable! Object distribution skipped and could lead to a potentially un-owned or owner-mismatched {nameof(NetworkObject)}!");
1975+
}
19731976
continue;
19741977
}
19751978
// Transfer ownership of all distributable =or= transferrable children with the same owner to the same client to preserve the sibling ownership tree.

0 commit comments

Comments
 (0)