Archived on 2026-10-24. This is a historical implementation note, not current setup instructions or an active task list. Original claims, code examples, file paths, and completion statements have not all been revalidated. Use the current documentation and issue register for maintenance decisions.
MenuController Refactoring Summary¶
Overview¶
The MenuController has been refactored to separate generic menu functionality from MainMenu-specific logic. This allows MenuController to be reused across different scenes (MainMenu, Stage, etc.) while each scene manager handles its specific game flow.
Architecture Changes¶
1. New Components¶
RootAnimationData (Assets/Script/App/UI/Shared/RootAnimationData.cs)¶
A serializable class that defines animation data for root UI elements:
- CanvasGroup: The UI element to animate
- AnimationDirection: Direction from which the UI slides in (LEFT, RIGHT, UP, DOWN)
- AnimationSpeed: Duration of the animation in seconds
- Delay: Delay before the animation starts
MainMenuManager (Assets/Script/App/Core/Managers/MainMenuManager.cs)¶
Manages MainMenu scene-specific logic: - Initializes MainMenu after hyperspace transition - Handles game flow (PlayGame, StartTutorial, QuitGame) - Manages quit confirmation flow - Handles back/quit text localization - Coordinates with MenuController for page navigation
2. Refactored MenuController (Assets/Script/App/UI/Controllers/MenuController.cs)¶
Now namespace: TinyChaos.UI.Controllers
Removed: - Game-specific methods (PlayGame, PlayGameExperimental, StartTutorial, QuitGame) - MainMenu-specific logic (quit confirmation, back/quit text management) - Specific root UI fields (VersionGroup, ExitButtonGroup)
Added:
- List<RootAnimationData> RootAnimations: Generic list of root UI animations
- event Action OnRootBackPressed: Allows scenes to customize back button behavior on root page
- event Action<bool> OnGateAnimationComplete: Allows scenes to handle logic after gate animation
- PushExitPage(Page): Generic method to push exit/confirmation pages
Kept: - Page stack management (push/pop) - First focus item handling - Gate animation control (scene transitions) - Generic back button handling with customizable behavior - Hyperspace transition support
File Structure¶
Assets/Script/
├── App/
│ ├── Core/
│ │ └── Managers/
│ │ └── MainMenuManager.cs (new)
│ ├── UI/
│ ├── Controllers/
│ │ └── MenuController.cs (refactored, namespace: TinyChaos.UI.Controllers)
│ └── Shared/
│ ├── RootAnimationData.cs (new)
│ └── Page.cs (no changes)
└── TinyChaos/
└── Utilities/
└── AnimFunc.cs (updated to add delay parameter to SlideIn)
Configuration Guide¶
MainMenu Scene Setup¶
- Add MenuController component to a GameObject in the MainMenu scene
- Set
InitialPage: The first page to show when menu initializes - Set
ExitPage: The quit confirmation page (optional) - Set
FirstFocusItem: The UI element to focus on initialization - Configure
RootAnimationslist:- Add entries for each root UI element (Version text, Exit button, etc.)
- Set CanvasGroup, AnimationDirection, AnimationSpeed, and Delay for each
- Configure
Gate Transitions: Assign gate GameObject references - Configure
Page Animation Eases: Set entry/exit easing functions -
Set
Hyperspace Transition: Assign the HyperspaceTransition component (optional) -
Add MainMenuManager component to a GameObject in the MainMenu scene
- Set
MenuController: Reference to the MenuController (or leave null to find instance) - Set
InitialPage: Same as MenuController's InitialPage - Set
QuitConfirmationPage: The quit confirmation page - Set
FirstFocusItem: Same as MenuController's FirstFocusItem -
Configure
Localization: back_String and quit_String references -
Hyperspace Integration
- The HyperspaceTransition component should call
MainMenuManager.InitializeAfterHyperspace()after transition completes - Or call
MenuController.StartHyperspaceTransition()from SplashUIController
Using MenuController in Other Scenes¶
For other scenes (e.g., Stage scene), you can use MenuController directly or create a scene-specific manager:
public class StageMenuManager : MonoBehaviour
{
[SerializeField] private MenuController menuController;
private void Awake()
{
menuController = MenuController.instance;
// Configure stage-specific behavior
menuController.OnRootBackPressed += HandleStageBackPressed;
menuController.OnGateAnimationComplete += HandleGateComplete;
}
private void HandleStageBackPressed()
{
// Show pause/settings menu instead of quit confirmation
ShowPauseMenu();
}
private void HandleGateComplete(bool isExperimental)
{
// Handle stage-specific logic after gate animation
StartStageGame();
}
}
Key Features¶
Event-Based Customization¶
OnRootBackPressed: Allows each scene to define what happens when back is pressed on the root pageOnGateAnimationComplete: Allows each scene to handle game start logic after gate animation
Reusable Animation System¶
- Root animations are now data-driven via
RootAnimationData - Supports multiple root UI elements with different animations and delays
- Easy to extend for new scenes
Clean Separation of Concerns¶
- MenuController: Generic page navigation and UI animation
- Scene Managers: Scene-specific logic and game flow
- Easy to test and maintain each component independently
Migration Notes¶
For Existing MainMenu Scene¶
- Replace
VersionGroupandExitButtonGroupwithRootAnimationslist: - Create entry for VersionGroup
- Create entry for ExitButtonGroup
-
Set appropriate AnimationDirection and AnimationSpeed for each
-
Move game logic from MenuController to MainMenuManager:
- Move PlayGame, PlayGameExperimental, StartTutorial, QuitGame to MainMenuManager
- Move quit confirmation logic to MainMenuManager
-
Move back/quit text logic to MainMenuManager
-
Update references:
- Update any UI buttons that called MenuController methods to call MainMenuManager methods instead
- Ensure MenuController instance is properly configured
For HyperspaceTransition Component¶
Update to call MainMenuManager.InitializeAfterHyperspace() instead of MenuController.InitializeMenuAfterTransition():
// Before
StartCoroutine(MenuController.instance.InitializeMenuAfterTransition());
// After
MainMenuManager mainMenuManager = FindObjectOfType<MainMenuManager>();
if (mainMenuManager != null)
{
StartCoroutine(mainMenuManager.InitializeAfterHyperspace());
}
Benefits¶
- Reusability: MenuController can now be used in any scene with page-based UI
- Maintainability: Separation of concerns makes code easier to understand and modify
- Flexibility: Event-based system allows easy customization per scene
- Scalability: Easy to add new scenes with similar menu systems
- Testability: Components can be tested independently
Future Refactoring¶
The GameMenuManager (used in gameplay scenes) can also be refactored to use this pattern: - Create a scene-specific manager (e.g., GameplayMenuManager) - Use MenuController for page navigation - Move game-specific logic to the scene manager - Configure OnRootBackPressed to show pause/settings menu instead of quit confirmation
Compatibility Notes¶
- All existing Page components continue to work without changes
- AnimFunc.SlideIn now supports an optional delay parameter
- MenuController namespace changed to
TinyChaos.UI.Controllers - Update any using statements or references accordingly