Files
2026-06-22 16:18:34 +02:00

103 lines
3.5 KiB
C#

using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace Ashwild.EditorTools
{
/// <summary>
/// Toggleable editor option that forces play mode to always start from the first build scene
/// (index 0, the boot/menu scene), no matter which scene is open. When enabled, pressing the
/// normal Play button boots from scene 0 and Unity automatically returns to the scene you were
/// editing once you stop — so you never have to manually open the menu scene to test.
/// The toggle shows a checkmark in the menu and its state persists across sessions.
/// </summary>
[InitializeOnLoad]
public static class PlayFromFirstScene
{
#region Constants
private const string MenuPath = "Tools/Ashwild/Play From Scene 0";
/// <summary>
/// EditorPrefs key persisting whether the "boot from scene 0" override is enabled.
/// </summary>
private const string EnabledKey = "Ashwild.PlayFromFirstScene.Enabled";
#endregion
#region Initialization
/// <summary>
/// Re-applies the saved toggle state after every domain reload so the play-mode start scene
/// stays bound even after a recompile.
/// </summary>
static PlayFromFirstScene()
{
EditorApplication.delayCall += () => ApplyStartScene(IsEnabled);
}
#endregion
#region Menu
/// <summary>
/// Flips the override on or off and immediately (un)binds the play-mode start scene.
/// </summary>
[MenuItem(MenuPath, priority = -100)]
public static void Toggle()
{
bool enabled = !IsEnabled;
EditorPrefs.SetBool(EnabledKey, enabled);
ApplyStartScene(enabled);
}
/// <summary>
/// Draws the checkmark next to the menu entry to reflect the current state.
/// </summary>
[MenuItem(MenuPath, validate = true)]
public static bool ToggleValidate()
{
Menu.SetChecked(MenuPath, IsEnabled);
return true;
}
#endregion
#region Internal Helpers
/// <summary>
/// Whether the override is currently enabled, read from persisted EditorPrefs.
/// </summary>
private static bool IsEnabled => EditorPrefs.GetBool(EnabledKey, false);
/// <summary>
/// Binds (or clears) Unity's playModeStartScene to build scene 0. While bound, every play
/// session starts there and returns to the open scene on stop; clearing restores the default
/// behaviour of playing the currently open scene. Logs and self-disables if scene 0 is missing.
/// </summary>
private static void ApplyStartScene(bool enabled)
{
if (!enabled)
{
EditorSceneManager.playModeStartScene = null;
return;
}
if (EditorBuildSettings.scenes.Length == 0 ||
string.IsNullOrEmpty(EditorBuildSettings.scenes[0].path))
{
Debug.LogError("[PlayFromFirstScene] No scene at Build Settings index 0 — add the menu scene there.");
EditorPrefs.SetBool(EnabledKey, false);
EditorSceneManager.playModeStartScene = null;
return;
}
SceneAsset firstScene =
AssetDatabase.LoadAssetAtPath<SceneAsset>(EditorBuildSettings.scenes[0].path);
EditorSceneManager.playModeStartScene = firstScene;
}
#endregion
}
}