diff --git a/Editor/Commandline.cs b/Editor/Commandline.cs
index 15457b9..a731655 100644
--- a/Editor/Commandline.cs
+++ b/Editor/Commandline.cs
@@ -55,9 +55,6 @@ private static void Bootstrap()
// Set first open Scene
EditorSceneManager.playModeStartScene = myWantedStartScene;
- // Register event handler for terminate autopilot
- EditorApplication.playModeStateChanged += OnChangePlayModeState;
-
// Activate autopilot and enter play mode
var state = AutopilotState.Instance;
state.launchFrom = LaunchType.Commandline;
@@ -97,26 +94,5 @@ private static void FocusGameView()
var gameView = assembly.GetType(viewClass);
EditorWindow.GetWindow(gameView, false, null, true);
}
-
- ///
- /// Stop autopilot on play mode exit event when run on Unity editor.
- /// Not called when invoked from play mode (not registered in event listener).
- ///
- ///
- private static void OnChangePlayModeState(PlayModeStateChange playModeStateChange)
- {
- if (playModeStateChange != PlayModeStateChange.EnteredEditMode)
- {
- return;
- }
-
- EditorApplication.playModeStateChanged -= OnChangePlayModeState;
-
- // Exit Unity when returning from play mode to edit mode.
- // Because it may freeze when exiting without going through edit mode.
- var exitCode = (int)AutopilotState.Instance.exitCode;
- Debug.Log($"Exit Unity-editor by autopilot, exit code: {(int)exitCode}");
- EditorApplication.Exit(exitCode);
- }
}
}
diff --git a/README.md b/README.md
index 207cebb..ca487d1 100644
--- a/README.md
+++ b/README.md
@@ -665,7 +665,15 @@ It can specify the same arguments as when running in the editor.
## Troubleshooting
-### Autopilot runs on its own in play mode.
+### Autopilot is stopped, but the Run button in AutopilotSettings does not appear
+
+The `AutopilotState.asset` that persists in Anjin's execution state may be in an incorrect state.
+Open it in the inspector and click the **Reset** button.
+
+If this does not solve the problem, try deleting `AutopilotState.asset`.
+
+
+### Autopilot runs on its own in play mode
The `AutopilotState.asset` that persists in Anjin's execution state may be in an incorrect state.
Open it in the inspector and click the **Reset** button.
diff --git a/README_ja.md b/README_ja.md
index 2e4e8c1..004aee3 100644
--- a/README_ja.md
+++ b/README_ja.md
@@ -676,6 +676,14 @@ $(ROM) -LAUNCH_AUTOPILOT_SETTINGS Path/To/AutopilotSettings
## トラブルシューティング
+### オートパイロットは停止しているのに AutopilotSettings の Run ボタンが表示されない
+
+Anjinの実行状態を永続化している `AutopilotState.asset` が不正な状態になっている恐れがあります。
+インスペクタで開いて**Reset**ボタンをクリックしてください。
+
+それでも解決しない場合、 `AutopilotState.asset` を削除してみてください。
+
+
### プロジェクトを再生モードにすると勝手にオートパイロットが動いてしまう
Anjinの実行状態を永続化している `AutopilotState.asset` が不正な状態になっている恐れがあります。
diff --git a/Runtime/Autopilot.cs b/Runtime/Autopilot.cs
index 31891e7..3a9ae80 100644
--- a/Runtime/Autopilot.cs
+++ b/Runtime/Autopilot.cs
@@ -10,6 +10,9 @@
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.SceneManagement;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
namespace DeNA.Anjin
{
@@ -71,6 +74,17 @@ private void Start()
throw new InvalidOperationException("Autopilot is not running");
}
+#if UNITY_EDITOR
+ if (_state.launchFrom == LaunchType.Commandline)
+ {
+ EditorApplication.playModeStateChanged += OnExitPlayModeToTerminateEditor;
+ }
+ else
+ {
+ EditorApplication.playModeStateChanged += OnExitPlayModeToTeardown;
+ }
+#endif
+
_logger = _settings.LoggerAsset.Logger;
// Note: Set a default logger if no logger settings. see: AutopilotSettings.Initialize method.
@@ -148,6 +162,13 @@ public async UniTask TerminateAsync(ExitCode exitCode, string message = null, st
_isTerminating = true;
+#if UNITY_EDITOR
+ if (_state.launchFrom != LaunchType.Commandline)
+ {
+ EditorApplication.playModeStateChanged -= OnExitPlayModeToTeardown;
+ }
+#endif
+
if (reporting && _state.IsRunning && _settings.Reporter != null)
{
await _settings.Reporter.PostReportAsync(message, stackTrace, exitCode, token);
@@ -164,5 +185,44 @@ public void Terminate(ExitCode exitCode, string logString = null, string stackTr
{
TerminateAsync(exitCode, logString, stackTrace).Forget();
}
+
+#if UNITY_EDITOR
+ ///
+ /// Stop autopilot on play mode exit event when run on Unity editor.
+ /// Not called when invoked from play mode (not registered in event listener).
+ ///
+ private static void OnExitPlayModeToTerminateEditor(PlayModeStateChange playModeStateChange)
+ {
+ if (playModeStateChange != PlayModeStateChange.EnteredEditMode)
+ {
+ return;
+ }
+
+ EditorApplication.playModeStateChanged -= OnExitPlayModeToTerminateEditor;
+
+ // Exit Unity when returning from play mode to edit mode.
+ // Because it may freeze when exiting without going through edit mode.
+ var exitCode = (int)AutopilotState.Instance.exitCode;
+ Debug.Log($"Exit Unity-editor by autopilot, exit code: {exitCode}");
+ EditorApplication.Exit(exitCode);
+ }
+
+ ///
+ /// Teardown when Play Mode is stopped while the Autopilot is running.
+ ///
+ private static void OnExitPlayModeToTeardown(PlayModeStateChange playModeStateChange)
+ {
+ if (playModeStateChange != PlayModeStateChange.EnteredEditMode)
+ {
+ return;
+ }
+
+ EditorApplication.playModeStateChanged -= OnExitPlayModeToTeardown;
+
+ // Teardown when Play Mode is stopped while the Autopilot is running.
+ Debug.LogWarning("Play Mode is stopped while the Autopilot is running");
+ AutopilotState.Instance.Reset();
+ }
+#endif
}
}
diff --git a/Runtime/Launcher.cs b/Runtime/Launcher.cs
index 493b3a8..be45d90 100644
--- a/Runtime/Launcher.cs
+++ b/Runtime/Launcher.cs
@@ -247,7 +247,7 @@ internal static async UniTaskVoid TeardownLaunchAutopilotAsync(AutopilotState st
await UniTask.NextFrame();
#if UNITY_EDITOR
EditorApplication.isPlaying = false;
- // Note: If launched from the command line, `DeNA.Anjin.Editor.Commandline.OnChangePlayModeState()` will be called, and the Unity editor will be terminated.
+ // Note: If launched from the command line, `DeNA.Anjin.Autopilot.OnExitPlayModeToTerminateEditor()` will be called, and the Unity editor will be terminated.
#endif
}
else