Un contrôleur simple pour gérer le chargement/déchargement multi-scène (Additive) dans Unity, avec une Fluent API pour construire des plans de transition.
Le package du projet se trouve dans les releases GitHub : Releases · GamagoRat/unity-multiscene
L'implémentation s'inspire de cette vidéo : https://www.youtube.com/watch?v=oejg12YyYyI
Ce document décrit l'implémentation et l'utilisation du SceneController et de sa Fluent API (SceneTransitionPlan).
Le package du projet se trouve dans les releases GitHub : https://github.com/GamagoRat/unity-multiscene/releases
- implémentation s'inspire largement de cette vidéo : https://www.youtube.com/watch?v=oejg12YyYyI
- Ce projet Unity utilise la fonctionnalité Multi-Scene pour gérer plusieurs scènes (1 scène principale qui load et unload d'autres scènes secondaires)
- Le script "SceneController" est un singleton accessible depuis toutes les scènes et permet de charger et décharger des scènes secondaires
- Utilise une fluent API pour charger et décharger les scènes secondaires
- Pour faire des effets de transition, création d'une classe abstraite
TransitionEffect(nommée parfoisSceneTransitiondans la documentation) qui sera héritée par des classes concrètes (exemple fourni utilisant un Animator).
Exemples de structure de scènes :
-
Une scène "Core"
- possède le SceneController
- possède "ProjectManager" qui charge la scène de menu principal au démarrage
- un Canvas avec un Panel ; le Canvas possède un
AnimatorTransitionEffectqui hérite deTransitionEffectet permet de faire des transitions avec des animations. Attention : le Canvas de transition doit avoir une priorité haute pour passer au-dessus des autres canvases des autres scènes.
-
Une scène "MainMenu"
- possède un Canvas avec des boutons, dont un "Play" qui charge la scène "Game" en utilisant la fluent API.
- possède
MainMenuManagerqui gère les interactions du menu principal (fonction qui transitionne vers la scène game).
-
Une scène "Game"
- possède un Canvas avec un bouton "Stop" qui décharge la scène "Game" et recharge la scène "MainMenu" en utilisant la fluent API (permet de décharger les ressources 3D).
- possède
GameManagerqui gère les interactions du jeu (fonction qui transitionne vers la scène main menu).
SceneDatabase définit des constantes pour les noms des scènes secondaires (MainMenu, Game) ainsi que des slots qui définissent les endroits dans la hiérarchie où les scènes secondaires seront chargées (MainMenuSlot, GameSlot).
- Pour tester : ouvrir la scène "Core" et lancer le jeu. Le menu principal devrait apparaître avec une transition. Cliquer sur "Play" pour charger la scène de jeu avec une transition, puis cliquer sur "Stop" pour revenir au menu principal avec une transition.
- SceneController est un singleton destiné à être placé dans la scène "Core" (ou scène centrale) et gère le chargement/déchargement de scènes secondaires en mode Additive.
- Il expose une API fluide pour construire un plan de transition (SceneTransitionPlan) puis l'exécuter.
- Le contrôleur garde en mémoire les scènes chargées par "slot" (clé logique → nom de scène) afin de pouvoir remplacer ou décharger facilement des scènes.
- Le système supporte des effets de transition (TransitionEffect) et le nettoyage des assets non utilisés.
- Chargement en Additive : les scènes secondaires sont chargées via
SceneManager.LoadSceneAsync(..., LoadSceneMode.Additive). - Active scene : on peut choisir quelle scène deviendra la scène active après le chargement.
- Slots : un
slotKeyest une clé logique (ex:MainMenuSlot,Session) qui identifie l'emplacement de la scène dans la hiérarchie ou la logique du projet. - isBusy : empêche l'exécution simultanée de plusieurs transitions. Si un plan est déjà exécuté, un nouvel appel loggue un warning et est ignoré.
Utilisation typique :
unity-multiscene/Assets/example/Scripts/GameManager.cs
Lines 7 to 12 in a75e0d3
Méthodes disponibles :
-
NewTransition()
- Crée et renvoie un nouvel objet
SceneTransitionPlan.
- Crée et renvoie un nouvel objet
-
Load(string slotKey, string sceneName, bool setActive = false)
- slotKey : identifiant logique du slot.
- sceneName : nom de la scène Unity (doit être présent dans les Build Settings).
- setActive : si
true, la scène sera définie comme active après le chargement. - Comportement : remplace la valeur du dictionnaire
ScenesToLoadpour la cléslotKey(écrase la valeur précédente si existante).
-
Unload(string slotKey)
- Ajoute
slotKeyà la listeScenesToUnload. Lors de l'exécution, la scène enregistrée pour ce slot (si présente) sera déchargée.
- Ajoute
-
WithOverlay()
- Active l'option
Overlaypour le plan. Si unTransitionEffectest configuré sur leSceneController,FadeIn()est appelé avant les opérations etFadeOut()après, permettant un effet visuel (ex: écran de transition).
- Active l'option
-
WithClearUnusedAssets()
- Active
ClearUnusedAssets: après les déchargements,Resources.UnloadUnusedAssets()sera exécuté pour libérer la mémoire des assets non référencés.
- Active
-
Perform()
- Envoie le plan au
SceneControllerviaExecutePlan(this)et retourne la Coroutine d'exécution. Ne bloque pas le thread principal — la gestion est asynchrone via Coroutine.
- Envoie le plan au
- Si
Overlay == trueet unTransitionEffectest assigné :FadeIn()(attente de la coroutine), puis courte pause (0.5s).
- Déchargement : parcourt
ScenesToUnloadet appelleUnloadSceneAsyncpour chaque slot (résolu en nom de scène depuisloadedScenesBySlot). - Si
ClearUnusedAssets: appelleResources.UnloadUnusedAssets()et attend la fin. - Chargement : parcourt
ScenesToLoad(slotKey → sceneName) :- Si le slot contient déjà une scène, elle est déchargée (
UnloadSceneRoutine). - Charge la nouvelle scène en Additive via
LoadSceneAsync. - Gère
allowSceneActivationpour contrôler le moment d'activation. - Si la scène est marquée active (
ActiveSceneName == sceneName), appelleSceneManager.SetActiveScene. - Met à jour
loadedScenesBySlot[slotKey] = sceneName.
- Si le slot contient déjà une scène, elle est déchargée (
- Si
Overlay == trueetTransitionEffectprésent :FadeOut(). - Réinitialise
isBusy = false.
- Type abstrait :
unity-multiscene/Assets/Scripts/TransitionEffect.cs
Lines 4 to 8 in a75e0d3
- Exemple concret : un
AnimatorTransitionEffectqui utilise un Animator pour animer un canvas de transition. - Important : si l'effet utilise un Canvas, assurer que sa priorité (Sorting Layer / Order in Layer) est supérieure afin qu'il apparaisse au-dessus des autres UI des scènes chargées.
- Charger le menu au démarrage (ProjectManager) :
unity-multiscene/Assets/example/Scripts/ProjectManager.cs
Lines 7 to 9 in a75e0d3
- Depuis le menu, démarrer le jeu (MainMenuManager) :
unity-multiscene/Assets/example/Scripts/MainMenuManager.cs
Lines 7 to 12 in a75e0d3
- Depuis le jeu, retourner au menu (GameManager) :
unity-multiscene/Assets/example/Scripts/GameManager.cs
Lines 7 to 12 in a75e0d3
- Toujours s'assurer que les
sceneNameutilisés sont listés dans les Build Settings de Unity. - Utiliser des constantes (ex:
SceneDatabase) pour éviter les erreurs de frappe dans les noms et slots. - Placer le
SceneControllerdans une scène persistante (par ex. "Core") et marquer l'objetDontDestroyOnLoadsi nécessaire (selon l'architecture du projet). - Testez les effets de transition avec un canvas dédié ayant une priorité d'affichage élevée.
- Évitez de lancer plusieurs
.Perform()simultanés —isBusyprotège mais un contrôle applicatif peut améliorer l'UX.
- Warning "SceneController is busy executing another plan." : attendre la fin de la coroutine ou vérifier la logique appelante.
- Scène non trouvée / LoadSceneAsync retourne null : vérifier le nom exact et qu'il est inclus dans les Build Settings.
- Problèmes d'UI masquée pendant la transition : vérifier l'ordre des canvases et l'alpha/visibilité de l'effet de transition.