Skip to content

With Auto Refresh Enabled, an external Scene change shows the modified-externally dialog after Play Mode Stop, and answering it can crash Unity 2022.3 #3047

Description

@hatayama

Summary

The package already keeps Unity's "The open scene(s) have been modified externally — Ignore / Reload" dialog away from the common paths. uloop compile runs an external Scene change preflight, and a focus return runs another (see docs/focus-return-asset-handling.md). Two gaps remain:

  1. With Auto Refresh Enabled, an external Scene change that is not followed by a focus return shows the dialog right after Play Mode stops. It then blocks uloop control-play-mode --action Stop.
  2. Answering the dialog can crash Unity 2022.3. This makes gap 1, and any other way the dialog appears, more costly than a stalled command.

Gap 1: dialog after Stop with Auto Refresh Enabled

Observed on Unity 2022.3.62f3, macOS:

  1. A Scene saved under Assets/ is open in the Editor with no unsaved changes, and Auto Refresh is set to Enabled.
  2. The Scene file is changed on disk (a root GameObject renamed with sed) while no focus return follows. The change happened while Unity was focused. The same would happen with an Editor that stays unfocused throughout.
  3. uloop control-play-mode --action Play starts Play Mode without a dialog, running the in-memory (old) Scene content.
  4. uloop control-play-mode --action Stop: the dialog appears as the Editor returns to Edit Mode, and the Stop request does not return until it is answered.

With Auto Refresh Disabled, the same Stop returned to Edit Mode and loaded the new file content for the clean Scene silently.

Probable cause: the focus-return preflight is deferred during Play Mode and runs on EnteredEditMode only when a focus return was actually deferred. Here no focus return happened, so nothing reloads the changed Scene before Unity's own tick raises the dialog. This has not been confirmed in code.

What we know works: calling AssetDatabase.Refresh() and reopening the clean Scene in the same frame, before the next Editor tick, prevented the dialog. Reopening the Scene before the refresh did not. That matches the existing compile preflight, which imports the changed Scene first and then reloads it.

A possible fix is to run the fingerprint comparison on EnteredEditMode whenever a Scene changed on disk, whether or not a focus return was deferred. Whether that runs before Unity's tick handler on the Auto Refresh path still has to be checked.

Gap 2: answering the dialog crashed the Editor

On the same Editor, answering the dialog crashed Unity twice, once with Ignore and once with Reload. Both crashes were SIGSEGV (KERN_INVALID_ADDRESS at 0x38) inside EditorSceneManager::HandleOpenScenesChangeOnDisk(), called from EditorSceneManager::OnApplicationTick(). One further answer did not crash. In both crashes a uloop request was waiting for the Editor while the dialog was up (an execute-dynamic-code call, and the Stop above). Whether that pending request is involved is unconfirmed.

Open questions

  • Whether Unity 6 behaves the same for both gaps.
  • Whether a Prefab Stage has the same gap after Stop (it has its own "Prefab Has Been Changed on Disk" prompt).

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions