Repository navigation
feat: object pooling for hybrid prefab instances - #4247
NoelStephensUnity wants to merge 2 commits into
Conversation
Server: a hybrid instance handed to an INetworkPrefabInstanceHandler now has its ghost despawned (GhostObject.Despawn), so reusing it spawns a new ghost. NetworkRigidbodyBase restores the authored kinematic state on despawn; the ghost captured the despawn-time kinematic state on respawn and replicated it. Client: N4E instantiates and destroys client ghost GameObjects itself, so two NGO systems run ahead of GhostGameObjectSpawnSystem and GhostGameObjectDespawnManagedSystem and route prefabs with a registered handler through it instead.
Two spawn/despawn cycles on UnifiedHost and UnifiedServer: the client takes and returns instances through its handler, the server reuses its pooled instances, and the server body stays dynamic after a pooled respawn.
| spawnedGhostMap.Remove(despawn.ghost); | ||
| } | ||
|
|
||
| var networkObjectId = networkObject.NetworkObjectId; |
There was a problem hiding this comment.
If a ghost despawns before NGO processes its spawn message, the delayed message can spawn the instance after it has returned to the pool. HybridPrefabHandlerSpawnSystem registers the instance using NetworkObjectBridge.NetworkObjectId.Value. NetworkObject.NetworkObjectId is assigned later by SetupOnSpawn, so networkObjectId here is zero or the previous spawn's ID. MarkNetworkObjectAsDestroying therefore removes the wrong entry, leaving TryGetGhostNetworkObjectForSpawn able to return the still-live pooled instance. Capture the current bridge ID before despawning the ghost. Use that ID to clear the pending registration.
🤖 Helpful? 👍/👎
| { | ||
| SetIsKinematic(m_OriginalKinematicState); | ||
| } | ||
| return; |
There was a problem hiding this comment.
A server hybrid body pooled after AttachToFixedJoint remains constrained to its previous target when spawned again. AttachToFixedJoint permits dynamic hybrid bodies with UseRigidBodyForMotion enabled. The new return bypasses DetachFromFixedJoint and NetworkRigidbodyConnections.Clear(). Consequently, FixedJoint.connectedBody and ParentBody survive when the handler merely deactivates the instance, as the new pooling test does. Keep the joint cleanup before the hybrid-specific return. Restore the authored kinematic state after that cleanup.
🤖 Helpful? 👍/👎
Codecov ReportAttention: Patch coverage is @@ Coverage Diff @@
## develop-3.x.x #4247 +/- ##
=================================================
- Coverage 76.73% 76.47% -0.27%
=================================================
Files 159 160 +1
Lines 28101 28209 +108
=================================================
+ Hits 21564 21572 +8
- Misses 6537 6637 +100
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes
|
|
Waiting for Emma's object pool work. |
Purpose of this PR
Hybrid (NetworkObject + GhostObject) prefabs can now be pooled with an
INetworkPrefabInstanceHandleron both the server and clients, under UnifiedHost and UnifiedServer. Before this, the server pooled its instances, but every respawned Rigidbody came back kinematic, and clients ignored the handler entirely.NetworkRigidbodysets on despawn. The ghost then replicated that kinematic state when the instance was spawned again.InstantiateandDestroywere never called.PR Scope:
NetworkRigidbodyBase: a hybrid instance on the server returns to its authored kinematic state on despawn.NetworkSpawnManager: a hybrid instance handed to a prefab handler has its ghost despawned first (including at shutdown), so the pooled GameObject is not linked to a ghost or a disposed world. Spawning it again spawns a new ghost.HybridPrefabHandlerSystems: for a prefab with a registered handler, the client takes the instance from the handler instead of letting N4E instantiate it, and returns it to the handler instead of letting N4E destroy it.NetworkObject.InitGhost: a handler instance is not registered twice.HybridPrefabHandlerPoolingTests(UnifiedHost and UnifiedServer): two spawn/despawn cycles in which the server and the client both reuse their pooled instances, and the server body stays dynamic.Out of scope:
ownerClientId. (The ghost arrives before NGO's spawn message, so the owner is not known yet.)Jira ticket
N/A
Changelog
Documentation
Testing & QA (How your changes can be verified during release Playtest)
Functional Testing
Manual testing :
Manual testing done(ngo-examples StressTest with pooling enabled, host and client)Automated 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?If any boxes above are checked the QA team will be automatically added as a PR reviewer.
Up-port
N/A (hybrid mode exists on develop-3.x.x only).
Backports
N/A (hybrid mode exists on develop-3.x.x only).