Skip to content

fix: NetworkBehaviour Property Initialization Updates #1785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

NoelStephensUnity
Copy link
Collaborator

Accessing specific properties of NetworkBehaviour can too easily cause exceptions to occur. Depending upon frequency of usage, they can also impact performance unnecessarily.

MTT-2785

Changelog

com.unity.netcode.gameobjects

  • Fixed: If you update multiple packages, create a new section with a new header for the other package.

Testing and Documentation

  • One test was updated.
  • The rest validate the change

Updating to more stable and performant NetworkBehaviour properties through changing the how and when the properties are set.
Really MessageOrdering and the SpawnRpcDespawn classes need to be reviewed and updated.  This fixes a few timing related issues that were exposed with this update.
Removing the update to HasNetworkObject
really only ever need to wait for almost 1 tic interval to make sure the GameObject and associated components are destroyed and the handler destroyed.
clarity in a comment
removing the NetworkManager.IsListening since that is part of how the property values are determined (host, client, server).
handling an unlikely condition where the ownership or property update is invoked and NetworkObject is null.
@NoelStephensUnity NoelStephensUnity requested a review from 0xFA11 March 8, 2022 21:46
@@ -237,40 +237,41 @@ internal void __endSendClientRpc(ref FastBufferWriter bufferWriter, uint rpcMeth
/// <summary>
/// Gets if the object is the the personal clients player object
/// </summary>
public bool IsLocalPlayer => NetworkObject.IsLocalPlayer;
public bool IsLocalPlayer => m_NetworkObject != null ? m_NetworkObject.IsLocalPlayer : false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this actually an improvement though? If the NO is null, I think IsLocalPlayer should be undefined / access should crash as we actually don't really know. If there's code later that wants to tolerate not having the NO set up yet, fine, then let that code do this check. Also, since we call this frequently...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I went ahead and made this a private set and just initialize it during the spawning/despawning stages.
It removes the processing overhead and is cleaner.

public ulong OwnerClientId => NetworkObject.OwnerClientId;
public ulong OwnerClientId { get; internal set; }

internal void UpdatePropertyStates()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
internal void UpdatePropertyStates()
internal void UpdateNetworkProperties()

Comment on lines 408 to 421
internal void UpdateOwnership()
{
if (NetworkObject != null)
{
IsOwnedByServer = NetworkObject.IsOwnedByServer;
IsOwner = NetworkObject.IsOwner;
OwnerClientId = NetworkObject.OwnerClientId;
}
else // Shouldn't happen, but if it does then just clear out everything
{
IsOwnedByServer = IsOwner = false;
OwnerClientId = 0;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

move this logic into UpdateNetworkProperties() and maintain updating all net props in one place. easier to maintain.


/// <summary>
/// Gets called when the local client gains ownership of this object
/// </summary>
public virtual void OnGainedOwnership() { }

internal void GainedOwnership()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
internal void GainedOwnership()
internal void InternalOnGainedOwnership()

/// <summary>
/// Gets called when we loose ownership of this object
/// </summary>
public virtual void OnLostOwnership() { }

internal void LostOwnership()
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
internal void LostOwnership()
internal void InternalOnLostOwnership()

Comment on lines 247 to 251
private bool m_IsServer;
/// <summary>
/// Gets if we are executing as server
/// </summary>
protected bool IsServer => IsRunning && NetworkManager.IsServer;
protected bool IsServer { get { return m_IsServer; } }
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd suggest a simpler syntax like:

protected bool IsServer { get; private set; }

and for other properties too :)

Copy link
Contributor

Choose a reason for hiding this comment

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

and you don't need to have another field to back it up.

@@ -366,21 +392,56 @@ protected NetworkBehaviour GetNetworkBehaviour(ushort behaviourId)

internal void InternalOnNetworkSpawn()
Copy link
Contributor

Choose a reason for hiding this comment

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

I like the fact that now we are relying on OnNetworkSpawn and OnNetworkDespawn now <3

@0xFA11 0xFA11 changed the title fix: mtt-2785 NetworkBehaviour Property Initialization Updates fix: NetworkBehaviour Property Initialization Updates Mar 9, 2022
Includes all of Fatih's suggested adjustments
Also, went ahead and just moved the invocation of OnNetworkSpawn and OnNetworkDespawn into the internal methods.
Coming to alternate solution of IsLocalPlayer to reduce the processing cost of the other implementation.
@NoelStephensUnity NoelStephensUnity marked this pull request as ready for review March 9, 2022 21:51
}
else // Shouldn't happen, but if so then set the properties to their default value;
{
OwnerClientId = NetworkObjectId = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this an error condition we should log? Would be a way to spot mis-use / regressions

@NoelStephensUnity NoelStephensUnity merged commit c7dc103 into develop Mar 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants