fix: hybrid prefab component gating and distributed authority rejection - #4184
Open
NoelStephensUnity wants to merge 5 commits into
Open
NoelStephensUnity wants to merge 5 commits into
NoelStephensUnity wants to merge 5 commits into
Conversation
A hybrid prefab's NetworkRigidbodyBase derivatives were destroyed at runtime so a user could try hybrid mode without first stripping components from the prefab. Removing an entry from ChildNetworkBehaviours is not safe: InitializeChildNetworkBehaviours rebuilds unconditionally and has five call sites, two of them the public GetNetworkBehaviourOrderIndex and GetNetworkBehaviourAtOrderIndex, while Destroy is deferred to end of frame. A rebuild in a later frame therefore renumbers every behaviour after the removed one, and the NetworkVariable half of object synchronization is positional with no id, so a one-entry disagreement corrupts the whole buffer for that object. NetworkTransform was already handled by early-returning on HasGhost rather than being destroyed - the removal behind UNIFIED_NETCODE_DESTROY was dead, that define exists nowhere. This extends the same treatment to NetworkRigidbodyBase and closes four NetworkTransform paths that had no gate: OnSynchronize, InternalOnNetworkPostSpawn, InternalOnNetworkSessionSynchronized and InternalOnNetworkObjectParentChanged. The first of those means a hybrid object no longer writes a full teleport state to every joining client. The rigidbody is now forced kinematic on non-server peers rather than destroyed, restored from m_OriginalKinematicState on destroy as the class already provided for. That decision is made at spawn, not during Awake, because Initialize runs from Awake where an in-scene placed instance has no session to ask whether it is the server. UnregisterRigidbody had no call sites and is now called from the gate, which is what keeps a second Initialize from leaving a registration pointing at a component that no longer drives anything. [RequireComponent(typeof(Rigidbody))] is unconditional again. Behind #if !UNIFIED_NETCODE it was stripped from every NetworkRigidbody in the project the moment N4E was installed, hybrid or not, after which NetworkRigidbodyBase dereferences a null rigidbody in Awake.
Distributed authority does not support hybrid prefabs. A start with any GhostObject prefab registered now fails in CanStart with an error naming each prefab, before Initialize replaces the transport with UnifiedNetcodeTransport. A hybrid prefab added during a distributed authority session is refused, so HasGhostPrefabs cannot switch the running session into hybrid mode and stop its send queue.
…refab-component-gating
|
Check the configuration's TOML syntax, permitted settings, and size limit. See the error below. Error message: Configuration content:# This is the configuration for the u-pr bot
# https://github.cds.internal.unity3d.com/unity/u-pr
# For configuration of this file:
# https://developer.portal.internal.unity.com/catalog/default/component/u-pr/docs/configuration/automatic_runs/
[github_app]
handle_pr_actions = ['opened', 'ready_for_review'] # PR events that auto-run pr_commands
pr_commands = ["/harness-review"] # what runs on those events
reviewer_commands = ["/harness-review"] # what runs when @u-pr is added as reviewer
|
There was a problem hiding this comment.
💡 Harness Review
The change keeps hybrid components present to preserve behaviour IDs and adds distributed authority prefab checks, but the checks and rigidbody gating miss several reachable paths.
Reviewed commit 03ba4e1
🤖 Helpful? 👍/👎
- NetworkRigidbodyBase no longer re-applies the authority kinematic rule on an ownership change for a hybrid prefab. - NetworkPrefabs recomputes HasGhostPrefabs on initialize, and keeps a single subscription to each NetworkPrefabsList (a prefab added to a list during a session was registered more than once). - RejectGhostPrefabs is set in Initialize, after SetRole accepts the start, so a failed start cannot leave it set. - A NetworkPrefab override with a hybrid source or target prefab is detected as a hybrid registration. N4E instantiates the server's prefab from the ghost type, so overrides are not supported for hybrid prefabs yet: a start with one registered fails in any topology, and one added during a session is rejected.
Codecov ReportAll modified and coverable lines are covered by tests ✅ @@ Coverage Diff @@
## develop-3.x.x #4184 +/- ##
==============================================
Coverage 78.19% 78.20%
==============================================
Files 153 153
Lines 26272 26276 +4
==============================================
+ Hits 20544 20548 +4
Misses 5728 5728
Flags with carried forward coverage won't be shown. Click here to find out more.
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose of this PR
This PR assures the
NetworkBehaviourIdvalues on hybrid prefabs are maintained by keepingNetworkTransformandNetworkRigidbodyeffectively a "nop" on the instance instead of destroying them at runtime like the POC was doing. Included in this PR, hybrid prefabs are rejected when using a distributed authority network topology.NetworkRigidbodyBasederived classes were originally destroyed in the POC during runtime on hybrid prefab instances. This PR keeps the components but turns them into "nop components". This fixes some edge cases:ChildNetworkBehaviourswhileDestroyis deferred to the end of the frame.NetworkBehaviourIdrelative, so any deviation from the original indices could break delta synchronization.NetworkRigidbodyBasenow early-exits onHasGhostsimilar toNetworkTransform. The body is made kinematic on every peer except the server at spawn, and its authored kinematic state is restored on destroy.NetworkTransform, the new owner's body would become dynamic).NetworkTransformneeded additionalHasGhostgating withinOnSynchronize,InternalOnNetworkPostSpawn,InternalOnNetworkSessionSynchronizedandInternalOnNetworkObjectParentChanged. A hybrid object no longer writes a full transform state to every late joining client.NetworkTransform.UnregisterRigidbodyhad no call sites. It is now called from the gate, so reparenting a hybrid object that has aNetworkRigidbodyno longer dereferences a destroyed component.[RequireComponent(typeof(Rigidbody))]and[RequireComponent(typeof(Rigidbody2D))]are unconditional again. UnderUNIFIED_NETCODEthey were dropped from everyNetworkRigidbodyin the project, hybrid or not.The final suggested pattern, if a user decides to keep the hybrid prefab setting, will be to completely remove
NetworkTransformandNetworkRigidbody.The
UNIFIED_NETCODE_DESTROYblock inNetworkObjectis removed (that define is never used and was a left over artifact from the POC).Distributed authority does not support hybrid prefabs:
UnifiedNetcodeTransportand attempt to start the session.NetworkManagerwill shutdown before attempting to start the session.NetworkPrefab overrides are not supported for hybrid prefabs (yet):
NetworkManagerwill not start (in any network topology).NetworkPrefabssubscribed to eachNetworkPrefabsListagain every time it was initialized, so a prefab added to a list during a session was registered more than once. It now keeps a single subscription, andHasGhostPrefabsis recomputed each time the prefabs are initialized.PR Scope:
NetworkObject,NetworkTransform,NetworkRigidbodyBase,NetworkRigidbody,NetworkRigidbody2D,NetworkManager,NetworkPrefabandNetworkPrefabs. All changes are withinUNIFIED_NETCODEpaths except theNetworkPrefabsListsubscription fix. No wire format changes.Out of scope:
NetworkRigidbodyintegration coverage (NetworkRigidbodyTestnever compiles because the test assembly is missing the physics2d versionDefine. This will be fixed in a separate PR using thefix/rigidbody-tests-never-compiledbranch).UnifiedNetcodeTransportis not restored after a hybrid session ends.NetworkClient.SetRoleleavesIsServerset when it rejects a distributed authorityStartServer, so destroying thatNetworkManagerthrows (plain NGO, both develop lines; will be fixed in a separate PR).Jira ticket
N/A
Changelog
NetworkPrefabsListwhile a session was running was registered more than once and logged a duplicateGlobalObjectIdHasherror.Documentation
Testing & QA (How your changes can be verified during release Playtest)
UnifiedHybridPrefabBehaviourIdTests(UnifiedHost)UnifiedHybridPrefabValidationTests(UnifiedHost)UNIFIED_TESTS=true, all runtime tests)NetworkTransform,NetworkRigidbodyandNetworkManagerStartExceptionTestsfixturesFunctional Testing
Manual testing :
Manual testing doneAutomated tests:
Covered by existing automated testsCovered by new automated testsDoes the change require QA team to:
Review automated tests?Execute manual tests?Provide feedback about the PR?Up-port
Not needed. This PR targets
develop-3.x.x.Backports
The hybrid prefab changes are not needed on
develop-2.0.0(hybrid prefabs exist ondevelop-3.x.xonly). TheNetworkPrefabsListsubscription fix applies todevelop-2.0.0as well, and a port will follow.