Skip to content

Conversation

EmandM
Copy link
Collaborator

@EmandM EmandM commented Sep 19, 2025

Purpose of this PR

Methods inside of properties are much less performant to access that fields or methods without properties.

This PR focusses on:

  1. Removing references to NetworkBehaviour.NetworkObject from within NetworkBehaviour. Instead using m_NetworkObject anywhere that will be called after the NetworkBehaviour is spawned.
    a. Ensure that the NetworkObject explicitly sets m_NetworkManager when it calculates whether or not a NetworkBehaviour belongs in it's ChildNetworkBehaviours list.
  2. Simplifies the areas where the NetworkBehaviour lifecycle callbacks are invoked
    a. Simplifies the callsites around NetworkBehaviour.OnLostOwnership and NetworkBehaviour.OnGainedOwnership
    b. Reduces loop duplication around NetworkBehaviour.OnNetworkSpawn

Jira ticket

Link to related jira ticket (Use the smart commits). Short version (e.g. MTT-123) also works and gets auto-linked
to be created.

Changelog

  • Fixed: Improved NetworkBehaviour performance.

Documentation

  • No documentation changes or additions were necessary.

Testing & QA (How your changes can be verified during release Playtest)

This change needs a full play of astroids, and potentially the OwnershipChanging demo. Everything here should be covered by the automated tests, but this is a hot enough codepath that playtesting is definitely needed here.

Functional Testing

Manual testing :

  • Manual testing done

Automated tests:

  • Covered by existing automated tests
  • Covered by new automated tests

Does the change require QA team to:

  • Review automated tests?
  • Execute manual tests?
  • Provide feedback about the PR?

If any boxes above are checked the QA team will be automatically added as a PR reviewer.

Backports

This is a pure performance improvement and so doesn't need a backport.

@EmandM EmandM requested a review from a team as a code owner September 19, 2025 15:46
@EmandM EmandM requested review from a team and NoelStephensUnity as code owners September 22, 2025 15:55
@michalChrobot
Copy link
Collaborator

When you will be ready you can ping me and I can organize the Playtest. Just note that I'm off next week

/// Invokes the <see cref="ChildNetworkBehaviours"/> <see cref="NetworkBehaviour.OnLostOwnership"/> and <see cref="NetworkBehaviour.OnGainedOwnership"/> events.
/// <see cref="NetworkSpawnManager.UpdateOwnershipTable"/> is called to update the ownership in-between the two callbacks.
/// </summary>
internal void InvokeBehaviourOnOwnershipChanged(ulong originalOwnerClientId, ulong newOwnerClientId)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nicely done!
Collapsed, organized, and unified.
🥇

{
networkObject.InvokeBehaviourOnGainedOwnership();
}
// Notify lost ownership, update the ownership, then notify gained ownership for the network behaviours
Copy link
Collaborator

Choose a reason for hiding this comment

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

Flex the unification!
:godmode:

// Always notify locally on the server when a new owner is assigned
networkObject.InvokeBehaviourOnGainedOwnership();
// Notify lost ownership, update the ownership, then notify gained ownership for the network behaviours
networkObject.InvokeBehaviourOnOwnershipChanged(originalOwner, clientId);
Copy link
Collaborator

Choose a reason for hiding this comment

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

🔔

protected IEnumerator WaitForSpawnedOnAllOrTimeOut(NetworkObject networkObject, TimeoutHelper timeOutHelper = null)
{
var networkObjectId = networkObject.GetComponent<NetworkObject>().NetworkObjectId;
var networkObjectId = networkObject.NetworkObjectId;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice addition!

Copy link
Collaborator

@NoelStephensUnity NoelStephensUnity left a comment

Choose a reason for hiding this comment

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

:godmode:

Very nice.... 👍

@NoelStephensUnity NoelStephensUnity enabled auto-merge (squash) September 24, 2025 20:40
@NoelStephensUnity NoelStephensUnity merged commit 47ed2dd into develop-2.0.0 Sep 25, 2025
27 checks passed
@NoelStephensUnity NoelStephensUnity deleted the chore/optimize-networkbehaviour-neworkobject-access branch September 25, 2025 00:12
NoelStephensUnity added a commit that referenced this pull request Sep 26, 2025
Changing #3687 adjustment to use the version of SpawnNetworkObjectLocally that accepts a SceneObject which doesn't invoke pre-spawn but does invoke post spawn and processes deferred messages.
These were moved in this PR to assure post spawn was invoked after the object was 100% done locally spawning and as a last step process any deferred messages targeting this object.
NoelStephensUnity added a commit that referenced this pull request Oct 18, 2025
… when InLocalSpace is true (#3664)

* fix

Assure that the local InLocalSpace field is updated to match the parented status.

* fix

Reset IsTeleporting and ExplicitSet after invoking OnAuthorityPushTransformState so these values are preserved for user script.

Automatically adjust InLocalSpace when spawning a NeworkObject based on the NetworkObject's current parented status when SwitchTransformSpaceWhenParented is enabled.

* update

Invoking the OnAuthorityPushTransformState and OnNetworkTransformStateUpdated when synchronizing in order to provide users with the NetworkTransformState used to synchronize a NetworkTransform when first spawned.

* update

Revert moving where IsTeleportingNextFrame and ExplicitSet are reset.
Add WasTeleported to NetworkTransformState in order to preserve whether the pushed state was teleported or not.

* update

Adding documentation updates.

* update

XML API update

* Doc pass on NetworkTransform additions

* fix

NetworkSpawnManager:
Relative to spawning only, process deferred messages after post spawn.

NetworkTransform:
Synchronize the SwitchTransformSpaceWhenParented flag when it changes on the authority side.
Perform an early check in CheckForStateChange for changes to SwitchTransformSpaceWhenParented.
Apply changes to SwitchTransformSpaceWhenParented when processing a state update on non-authority instance.

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

Co-authored-by: Amy Reeve <[email protected]>

* Update com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs

Co-authored-by: Amy Reeve <[email protected]>

* Update com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs

Co-authored-by: Amy Reeve <[email protected]>

* Update com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs

Co-authored-by: Amy Reeve <[email protected]>

* refactor

A complete refactoring of how parenting is handled when NetworkTransform.SwitchTransformSpaceWhenParented is enabled to provide a complete 1:1 match of (n) back-to-back parenting actions and/or many parenting actions that occur over several frames. This preserves the order of operations, sends 1 full state update plus an added parenting directive per action immediately, and then upon receiving the non-authority instances will apply the parenting, transform the local values and interpolators' queued entries  between transform spaces (world to local, local to world, or local to local).

* style

Standards/style fix.

* style - PVP

More hidden white spaces...

* update

Removing one line space

* update

Adding change log entry.

* update

Check if writing as binary resolves the CRLF issue.

* update

Reverting last change.
Removing a single line of code.

* update

Migrating all NetworkTransform serialization into the NetworkTransformMessage.
Removing legacy observers for the NetworkTransform.

* upate

Increment count after check when iterating through observers.

* style

remove whitespaces.

* test

Add a test to validate this PR.

* Apply suggestions from code review

Co-authored-by: Amy Reeve <[email protected]>

* doc: update

Adjusting based on the PR's recent updates.
Refactoring the physics section.
Moved the NetworkRigidbody content out of physics and into a new NetworkRigidbody section under componetns.
Moved physics up to the components layer.
Did a large update to the physics documentation and provided an additional walk through of  how to "parent" physics bodies using attachables.

* doc: style

Adding one suggested change I left out.

* style - PVP

Fixing trailing spaces.

* update

Further clarifying the update to NetworkObject.SpawnWithOwnership

* fix

If half float precision is enabled, then update the current half float position state after transforming the current position due to a change in the NetworkObject's status.

* test and style

Updating the SwitchTransformSpaceWhenParented test to validate using various NetworkTransform configurations (i.e. half precision, quaternion, quaternion compressed) while also parenting with world position stays enabled and disabled.

Removing trailing space in recent documentation update.

* update

adding additional changelog entries.

* update

reflecting the current version of this file from main branch.

* update

Try this one more time.

* update

Making NetworkTransformState.SwitchTransformSpaceWhenParented internal as it doesn't really need to be public for its use case.

* Docs pass on new content

* Reinstating note

* Updating landing page

* refactor

Relatively large change:

- Preserving order of operations by making the default network delivery be reliable fragmented sequenced with the exception of named, unnamed, and any message types adjusted explicitly by user code to use a different network delivery method.

- Adjusted parenting directive to allow the server to force a parenting directive on a NetworkTransform it does not have the motion authority over.

- The NetworkObjects to show now will be also processed in-between ticks to preserve order of operations.
  - NetworkObjects pending to be shown on the same frame as the tick update will still be processed during the tick update.

* update

Left out the half precision adjustment in the server-side edge case for back-to-back changes.

* update

Adding additional change log entries.

* update

Minor version increment.

* fix

Fix the issue where a user can still set InLocalSpace when SwitchTransformSpaceWhenParented is enabled.

* fix

Fix issue where client owner authority NetworkTransform would not set the right IsParented status when sending a parenting directive.

* fix

Assure MessageDelivery is initialized whether in editor or stand alone.

* refactor

Include any pending dirty NetworkVariable updates just prior to sending the Show/CreateObjectMessage.

* style - PVP

Removing un-used comment line to avoid PVP-124-2

* refactor

Better organizing NetworkBehaviourUpdater's methods to be a bit more modular in order to better handle how we handle force synchronizing NetworkVariables when showing a NetworkObject.

Mobed all of that logic from NetworkBehaviourUpdater to the late update section in NetworkManager.

* fix

Needed to check the inverse of whether either are true to determine if we should exit early in the NetworkBehaviourUpdater.

* fix

Removing debug log entry that is was added for troubleshooting an issue while making changes in this PR.
Not throwing an exception when getting a message type by actual message type (only used in DA codec tests). Instead, it now returns the default reliable fragmented sequenced.

* fix

Try this MessageDelivery fix for the codec test one more time.

* refactor and fix

Removed the extra byte per updated from the parenting directive and added it as a flag.
Fixed spawn no observers, show, and then parent issue where the initial parenting during spawn was causing issues with a back-to-back parenting message.

* fix

Only invoke OnDestroy if Singleton is not null during the application quit.
Resolved the issue where a server spawning an object with ownership that then changes the parent in the same frame with a NetworkTransform that has SwitchTransformSpaceWhenParented enabled was not applying the parenting directive (being sent to all observers) locally.

* fix

Regressed a previous fix when resolving the most current issue where generating a parent directive should only apply the parenting directive if it is the server and not the motion authority (whether local or world) and to assure if we are the motion authority we still set the m_PreviousParent in the event ownership changes and the NetworkTransform is using an owner authority motion model.

* update

Minor adjustment after merge.
Don't invoke NetworkManager.OnDestroy unless the singleton is null and the current instance is not listening.

* fix

If we suddenly stopped and trying to update non-existent NetworkTransform instances, then just reset the NetworkTransformTickRegistration system.

* fix

Allow NetworkObjects to run through the despawn process if they are destroyed by something like the UnityEngine SceneManager when unloading a scene. Added validation check against the NetworkObject's GameObject's scene (IsValid) and whether the scene is loaded or not to determine if an error message should be logged or if it is just being destroyed due to the scene being unloaded (abrupt unloading like exiting play mode while in a session).

* fix

If a NetworkTransformMessage is received while in the middle of shutting down, then do not attempt to process it.

* fix

Changing #3687 adjustment to use the version of SpawnNetworkObjectLocally that accepts a SceneObject which doesn't invoke pre-spawn but does invoke post spawn and processes deferred messages.
These were moved in this PR to assure post spawn was invoked after the object was 100% done locally spawning and as a last step process any deferred messages targeting this object.

* test

Made a few adjustments to this test in order to debug, added additional logging, and marked this test as needing to be updated (and extended).

* style

removing whitespaces

* test - fix

Validating clients had initialized was some how was encapsulated within a verbose debug check. Not sure why this was passing before other than certain messages might have always been processed out of order before...?

* fix and update

Removing the previously removed post spawn invocation from the common spawn method (missed when merging).

Renaming the local spawn methods to reflect the context of the local spawn (i.e. authority is the first to spawn and then notify where non-authority is invoked by the authority's CreateObjectMessage). It will help keep the context clear (possible area to merge into one with a flag to determine if it is an authority or non-authority spawn action).

* test

Minor adjustments to the test that caught this issue.
Added logs and condensed NetworkUpdate.

* style

insert a whitespace

* style - PVP

Removing whitespace at the end of the comment

* refactor

Minor performance gain by using a pre-defined static network delivery that is registered by message type  within MessageDelivery.

* fix

Removing using directive.
Reverting changes to NetworkVariableCollectionsTests

* update

Minor code clean up with a handful of additional comments.

* style

Adjusting internal comments for clarity purposes.

* refactor

This includes a different approach to handling  buffered linear interpolation conversion when switching transform space.

* update

Making parent internal.

* update

Removing additional script not used.

* refactor

Noticed an issue with the world space approach and rotating platforms (parents).
This is a refactor of the same kind of approach (i.e. interpolator handles transform space updates) with the addition of tracking each measurement's parent, handling any transform space conversion if the current parent is different from the measurement's parent, and just keeping everything transform space relative.

* fix

Set the target parent when initializing.
Added additional checks when getting the current interpolated value to handle the interpolation frames between the current and next measurement states.

* fix

This resolves the issue where there was a de-synch between converting transform spaces.

* update

Removing left over debug script.

* fix

This resolves the broken half float issue.

* fix

Fixing issue with synch when SwitchTransformSpaceWhenParented is disabled.

* fix

Allow a full teleport when using SwitchTransformSpaceWhenParented.

* fix - refactor

This refactors the previous "fix" to preserve the teleport flag but also keeps the original logic which is needed for when SwitchTransformSpaceWhenParented is disabled.

* test - wip

This includes a more modular framework for generating order of operation sequences in order to create a wide range of tests that validate specific order of operation actions are processed and applied on the non-authority instances as they were on the authority instance.

* test

Updated the order of operations test to include 10 of the 11 spawn sequence ordering tests.
Added `NetcodeIntegrationTest.SpawnObjectInstance` that allows you to create an instance of a prefab and pass the instance in to be spawned through the normal integration test spawn process.

* style

Removing single white space after an (internal) comment...

* style

removing more whitespace.

* Test-update

Some general clean up and separating areas of the NetworkTransformOrderOfOperations by region to help with navigating through the different parts.

* test

Adding the 11th test to the order of operations test.

* update

Adding missing change log entry.

* test

Check on the receiving side of the `ReferenceTeleportRpc` call that only the motion authority applies the teleport.

* test-fix

Moving the motion authority check within the check to assure the SpawnSequenceController NetworkBehaviourReference is valid.

* doc

Updated some XML API documentation and corrected a typo in a comment.

---------

Co-authored-by: Amy Reeve <[email protected]>
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