0
\$\begingroup\$

I have a SceneManager class (code shown below) that I think should contain my "business logic" for loading scenes in some way that I want using SceneLoader. Right now I have methods for loading Main Menu, Gameplay and Persistent scenes. But what if I want to add in the future logic for loading Test Scene or any other. I will have to add new methods for each one of them. And it will repeat basic logic.

I mean, I can create enum and map it in dictionary and then have single method called LoadScene that receives enum as parameter, but I guess it' not that good either. I think that Strategy/Command might work... I guess? But I'm not sure, like, I want to use this class later, like, some screen will call SceneManager.LoadMainMenu when the user presses Main Menu button.

So... Am I right? Am I wrong? Maybe I overthink this?

Basically, ANY advice will be appreciated.

EDIT: SceneLoader and IScene are irrelevant here. SceneLoader just has methods for loading and unloading requested scenes. IScene just stores the reference to the scene and name. Why does LoadGameplay loads two IScenes, because I'm splitting my UI and the rest for Gameplay. Menu doesn't need anything special, so it's just UI scene. This is again isn't relevant that much.

public class SceneManager
    {
        [Serializable]
        public class Settings
        {
            public GameScene MainMenu;
            public GameScene Gameplay;
            public GameScene PersistentManagers;
        }

        private readonly Settings _settings;
        private readonly SceneLoader _sceneLoader;

        private readonly List<IScene> _loadedScenes;

        public SceneManager(Settings settings, SceneLoader sceneLoader)
        {
            _loadedScenes = new List<IScene>();
            _settings = settings;
            _sceneLoader = sceneLoader;
        }

        public async UniTask LoadPersistentManagers()
        {
            var persistentManagers = _settings.PersistentManagers;
            var scenesToLoad = new IScene[] { persistentManagers.ManagersScene };

            await _sceneLoader.RequestSceneLoadingAsync(scenesToLoad);
        }

        public async UniTask LoadMainMenu()
        {
            var mainMenu = _settings.MainMenu;
            var scenesToLoad = new IScene[] { mainMenu.MenuScene };

            await UnloadLoadedScenes();

            await _sceneLoader.RequestSceneLoadingAsync(scenesToLoad);

            _loadedScenes.AddRange(scenesToLoad);
        }

        public async UniTask LoadGameplay()
        {
            var gameplay = _settings.Gameplay;
            var scenesToLoad = new IScene[] { gameplay.ManagersScene, gameplay.MenuScene };

            await UnloadLoadedScenes();

            await _sceneLoader.RequestSceneLoadingAsync(scenesToLoad);

            _loadedScenes.AddRange(scenesToLoad);
        }

        private async UniTask UnloadLoadedScenes()
        {
            if (_loadedScenes.Count != 0)
            {
                await _sceneLoader.RequestSceneUnloadingAsync(_loadedScenes);
            }
        }
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Please amend the question title to describe what your code does. \$\endgroup\$ Oct 2, 2022 at 5:46
  • 1
    \$\begingroup\$ This question seems to be a bit sketchy. What exactly is an IScene, and what does it mean for a scene to be "loaded"? Why does LoadGameplay load two IScenes? You might have to show more code so that the question makes sense to reviewers. \$\endgroup\$ Oct 2, 2022 at 6:30
  • \$\begingroup\$ please provide SceneLoader as well (with the required relative code). \$\endgroup\$
    – iSR5
    Oct 2, 2022 at 9:15
  • \$\begingroup\$ @PeterCsala (and others, I can't mentioned more users lol) I've added additional info, but I don't think it's necessary \$\endgroup\$
    – stroibot
    Oct 2, 2022 at 11:21
  • 1
    \$\begingroup\$ See How to Ask for site standards about question titles. So many people ask about what design patterns might be applicable, it's meaningless to put a design-patterns tag unless you have any specific design pattern in mind that is related to the code. If reviewers think there are any applicable design patterns, they'll mention it even if you don't request it. \$\endgroup\$ Oct 2, 2022 at 23:30

1 Answer 1

1
\$\begingroup\$

It is not a full code review, rather just two quick observations.

LoadXYZ

As I can see the LoadXYZ methods can be called in any order and as many times as you want (0 ... n).

If that is unintentional then please consider to use the fluent interface/method chaining:

var loadBuilder = SceneManager
  .WithSettings(...)
  .WithLoader(...)
  .RequestPersistentManagersLoading()
  .RequestMainMenuLoading()
  .RequestGamePlayLoading();

await loadBuilder.LoadAsync();

UnloadLoadedScenes

I don't know how does unity work but it might make sense to move this logic inside the Dispose method to help the consumer of this class to unload screens when they are disposing the manager.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.