Skip to content

fix: only send scene migrations to observers, and spawn a NetworkObject shown after a migration in its authority's scene - #4185

Merged
NoelStephensUnity merged 7 commits into
develop-2.0.0from
fix/scene-migration-observers
Oct 6, 2026
Merged

NoelStephensUnity merged 7 commits into
develop-2.0.0from
fix/scene-migration-observers

Conversation

@NoelStephensUnity

Copy link
Copy Markdown
Member

Purpose of this PR

This PR fixes two scene migration issues for NetworkObjects that are hidden from some clients: those clients no longer log an error when the NetworkObject moves to another scene, and they spawn it in the authority's scene when it is shown to them later. Both fixes apply in client-server and distributed authority modes.

PR Scope:

  • A scene migration (SceneEventType.ObjectSceneChanged) was sent to every connected client, including clients that did not observe the migrated NetworkObject and logged "Trying to synchronize NetworkObjectId but it was not spawned". It is now only sent to the clients that observe at least one migrated NetworkObject, and each client is only sent the NetworkObjects it observes. In distributed authority mode the owner applies the same filter; the CMB service is still sent every migrated NetworkObject, since it keeps the session state, and a migration the DAHost forwards is not filtered again.
  • A NetworkObject shown with NetworkShow after it migrated into another scene, while hidden from that client, was instantiated in the client's active scene, since the client was never sent that migration. The client now moves the spawned NetworkObject into its server-side scene (its owner's scene in distributed authority mode), as it already does during its initial synchronization (NetworkSceneManager.SynchronizeNetworkObjectScene).

New NetworkObjectSceneMigrationObserverTests (4 tests, Host / DAHost / Server) cover both fixes, and a late joining client's synchronization of a NetworkObject that is not in the active scene.

Out of this PR's scope:

  • None.

Jira ticket

TBD

Changelog

  • Fixed: Issue where moving a NetworkObject into another scene made the clients that did not observe it log "Trying to synchronize NetworkObjectId but it was not spawned". The scene migration is now only sent to the clients that observe the NetworkObject.
  • Fixed: Issue where a NetworkObject that was moved into another scene while hidden from a client spawned in that client's active scene when it was shown with NetworkShow, instead of the scene it is in on the server.

Documentation

  • No documentation changes or additions were necessary.

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

Headless PlayMode runs on 6000.5.3f1.

Run Passed Failed
All of Unity.Netcode.RuntimeTests 4710 0
NetworkObjectSceneMigrationObserverTests 12 0

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?

Up-port

These fixes are part of #4176 on develop-3.x.x.

Backports

Not needed.

🤖 Generated with Claude Code

…ct shown after a migration in the server's scene

ObjectSceneChanged was sent to every connected client, including clients that did not observe the migrated NetworkObjects and had never spawned them, which logged "Trying to synchronize NetworkObjectId but it was not spawned". In client-server mode it is now only sent to clients that observe at least one migrated NetworkObject, and each client is only sent the NetworkObjects it observes. Distributed authority is unchanged.

A client that starts observing a NetworkObject with NetworkShow after the NetworkObject migrated into another scene was never sent that migration, and instantiated the NetworkObject in its active scene. The client now moves a spawned NetworkObject into its server-side scene, as it already does for NetworkObjects that are part of its initial synchronization.
Distributed authority still sent a scene migration to every client, so clients that did not observe a migrated NetworkObject logged "Trying to synchronize NetworkObjectId but it was not spawned", and a NetworkObject shown after it migrated spawned in the client's active scene.

The owner now only sends a migration to the clients that observe a migrated NetworkObject, as in client-server mode. The CMB service's own copy still includes every migrated NetworkObject, and a migration the DAHost forwards is not filtered again. A NetworkObject a distributed authority client spawns when it is shown is moved into its owner's scene. NetworkObjectSceneMigrationObserverTests now also runs as DAHost.
@NoelStephensUnity
NoelStephensUnity requested a review from a team as a code owner October 6, 2026 01:38
@u-pr

u-pr Bot commented Oct 6, 2026

Copy link
Copy Markdown

⚠️ Some settings were ignored in '.pr_agent.toml (repository root)' repo settings

Check the configuration's TOML syntax, permitted settings, and size limit. See the error below.


Error message:
Ignored prohibited settings: github_app.handle_pr_actions. Permitted settings were applied.

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

@NoelStephensUnity NoelStephensUnity mentioned this pull request Oct 6, 2026
1 of 6 tasks

@u-pr u-pr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Harness Review

Needs changes

The change filters scene migrations by observer and moves newly shown objects into their authority’s scene, but the filtering leaves a reachable distributed-authority migration unsent to the session-state service.

Reviewed commit b69f17b

🤖 Helpful? 👍/👎

…gration

Only the session owner sends the CMB service its own copy of a migration; a client that is not the session owner does not tell the service about objects only it observes.
@NoelStephensUnity

Copy link
Copy Markdown
Member Author

@u-pr please review again, your comment has been addressed.

@u-pr

u-pr Bot commented Oct 6, 2026

Copy link
Copy Markdown

Thanks for the clarification and the updated comment in commit c9ba676.

The explanation holds: because a non-session-owner DA client does not inform the CMB service about objects only it observes (SpawnWithObservers = false), there is no stale state on the service to update at the time of migration. When NetworkShow is subsequently called, the resulting CreateObjectMessage transmits the current scene handle, and the newly added SynchronizeNetworkObjectScene call ensures the object is moved into the correct scene upon spawning.

The updated comment in NetworkSceneManager.cs accurately reflects that only the session owner needs to send migrations directly to the CMB service when peer observer lists are empty. The test coverage in NetworkObjectSceneMigrationObserverTests across Host, DAHost, and Server verifies these paths well.

Everything looks good.

🤖 Helpful? 👍/👎

@codecov-github-com

codecov-github-com Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 90.54054% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...cts/Runtime/SceneManagement/NetworkSceneManager.cs 88.88% 5 Missing ⚠️
...eobjects/Runtime/SceneManagement/SceneEventData.cs 90.47% 2 Missing ⚠️
@@                Coverage Diff                @@
##           develop-2.0.0    #4185      +/-   ##
=================================================
+ Coverage          74.16%   74.21%   +0.04%     
=================================================
  Files                172      172              
  Lines              28144    28200      +56     
=================================================
+ Hits               20874    20929      +55     
- Misses              7270     7271       +1     
Flag Coverage Δ
NGOv2_project_testproject_ubuntu 73.83% <90.54%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../Runtime/Messaging/Messages/CreateObjectMessage.cs 87.19% <100.00%> (+0.65%) ⬆️
...eobjects/Runtime/SceneManagement/SceneEventData.cs 77.73% <90.47%> (+0.51%) ⬆️
...cts/Runtime/SceneManagement/NetworkSceneManager.cs 79.83% <88.88%> (+0.33%) ⬆️
Components Coverage Δ
com.unity.netcode.gameobjects 74.21% <90.54%> (+0.04%) ⬆️

ℹ️ Need help interpreting these results?

@NoelStephensUnity
NoelStephensUnity enabled auto-merge (squash) October 6, 2026 15:51
@NoelStephensUnity
NoelStephensUnity merged commit 5982716 into develop-2.0.0 Oct 6, 2026
25 of 26 checks passed
@NoelStephensUnity
NoelStephensUnity deleted the fix/scene-migration-observers branch October 6, 2026 23:23
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.

2 participants