Skip to content

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

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

  1. Add MenuController component to a GameObject in the MainMenu scene
  2. Set InitialPage: The first page to show when menu initializes
  3. Set ExitPage: The quit confirmation page (optional)
  4. Set FirstFocusItem: The UI element to focus on initialization
  5. Configure RootAnimations list:
    • Add entries for each root UI element (Version text, Exit button, etc.)
    • Set CanvasGroup, AnimationDirection, AnimationSpeed, and Delay for each
  6. Configure Gate Transitions: Assign gate GameObject references
  7. Configure Page Animation Eases: Set entry/exit easing functions
  8. Set Hyperspace Transition: Assign the HyperspaceTransition component (optional)

  9. Add MainMenuManager component to a GameObject in the MainMenu scene

  10. Set MenuController: Reference to the MenuController (or leave null to find instance)
  11. Set InitialPage: Same as MenuController's InitialPage
  12. Set QuitConfirmationPage: The quit confirmation page
  13. Set FirstFocusItem: Same as MenuController's FirstFocusItem
  14. Configure Localization: back_String and quit_String references

  15. Hyperspace Integration

  16. The HyperspaceTransition component should call MainMenuManager.InitializeAfterHyperspace() after transition completes
  17. 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 page
  • OnGateAnimationComplete: 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

  1. Replace VersionGroup and ExitButtonGroup with RootAnimations list:
  2. Create entry for VersionGroup
  3. Create entry for ExitButtonGroup
  4. Set appropriate AnimationDirection and AnimationSpeed for each

  5. Move game logic from MenuController to MainMenuManager:

  6. Move PlayGame, PlayGameExperimental, StartTutorial, QuitGame to MainMenuManager
  7. Move quit confirmation logic to MainMenuManager
  8. Move back/quit text logic to MainMenuManager

  9. Update references:

  10. Update any UI buttons that called MenuController methods to call MainMenuManager methods instead
  11. 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

  1. Reusability: MenuController can now be used in any scene with page-based UI
  2. Maintainability: Separation of concerns makes code easier to understand and modify
  3. Flexibility: Event-based system allows easy customization per scene
  4. Scalability: Easy to add new scenes with similar menu systems
  5. 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