hadashiA / VContainer

The extra fast, minimum code size, GC-free DI (Dependency Injection) library running on Unity Game Engine.
https://vcontainer.hadashikick.jp
MIT License
1.88k stars 163 forks source link

What is the best way to start game from any scene? #635

Closed Lowlet closed 3 months ago

Lowlet commented 6 months ago

I have RootLifetimeScope, this scope contains game state machine which has states like BootstrapState -> SplashScreenState -> MainMenuState -> GameplayState. Each state can load different scene and each scene has local SceneScope in it. After each state completed i want to enter next state and load next scene. I also want to be able to start game from any scene so for example if I start from MainMenu it should load global scope first, init all needes services in bootstrap state and skip loading splash screen scene. If I want to start from gameplay state I want to init bootstrap state and skip splash screen and main menu. What is the best way to implement this?

IaroslavGusiev commented 4 months ago
#if UNITY_EDITOR
[InitializeOnLoad]
public static class LoadBootstrapperScene
{
    private const string PreviousScenePath = "PREVIOUS_SCENE";

    static LoadBootstrapperScene() =>
        EditorApplication.playModeStateChanged += OnPlayModeStateChanged;

    private static void OnPlayModeStateChanged(PlayModeStateChange state)
    {
        if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode)
        {
            string currentPath = SceneManager.GetActiveScene().path;
            EditorPrefs.SetString(PreviousScenePath, currentPath);

            if (SceneManager.GetActiveScene().buildIndex == 0)
                return;

            if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
            {
                string path = EditorBuildSettings.scenes[0].path;
                try
                {
                    EditorSceneManager.OpenScene(path);
                }
                catch
                {
                    EditorApplication.isPlaying = false;
                    EditorApplication.ExitPlaymode();
                }
            }
            else
            {
                EditorApplication.isPlaying = false;
            }
        }

        if (!EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode)
        {
            string path = EditorPrefs.GetString(PreviousScenePath);
            if (SceneManager.GetActiveScene().path == path)
                return;

            try
            {
                EditorSceneManager.OpenScene(path);
            }
            catch
            {
                Debug.LogError($"Cant load scene { path }");
                Application.Quit();
                EditorApplication.isPlaying = false;
            }
        }
    }
}
#endif
hadashiA commented 3 months ago

(IaroslavGusiev, thanks for your comment.)

I would also like to suggest to create an editor tool for startup.

In general, I think it would be more productive to create a tool that allows you to preview/edit the game from any point, rather than open and play a scene from the Project view.