12 KiB
Game UI/UX Architecture & Routing Specification (Unity UI Toolkit Edition)
This document outlines the complete structural layout, visual design, animations, and routing logic for the game's user interface, specifically optimized for Unity UI Toolkit. It serves as a direct guide for the associated .uxml, .uss, and .cs controller files.
1. Global Design System & Technical Approach
To maintain consistency and reduce development overhead, the UI is built using UXML templates, styled with USS, and driven by specific C# controllers mapped to your project structure.
Core UI Toolkit Architecture & File Mapping
- Controllers: UI logic is managed by dedicated scripts (UIManager.cs, MainMenuController.cs, LobbyController.cs, ProfileController.cs, SettingsController.cs, HUDController.cs).
- Views (UXML): Layouts are defined in modular files (MainMenu.uxml, Lobby.uxml, Profile.uxml, Settings.uxml, MainGameHUD.uxml).
- Styles (USS): Global styling is handled in Global.uss.
Reusable UI Components & Visual Styles
- Cursorless Navigation (Focus-Based Selection): The game does not display a standard OS cursor (Cursor.visible = false). Instead, the UI interprets mouse movement natively to determine focus. As the hidden cursor moves, the nearest interactive element highlights and scales up. This provides a smart, "snapping" feel to UI selection without needing a visible pointer.
- The "Osu-Style" Slanted Button: A custom VisualElement utilizing USS transform: skew(...) properties to create angled edges. Contains an inner text element counter-skewed to remain horizontal.
- Diagonal Split-Screen Container: Used in Lobby and Profile screens. Instead of a boring vertical line, the split is a sharp diagonal line (like a lightning slash).
- Implementation: Achieved by applying a negative skew to the Right Pane's parent container, and a positive skew to its inner content to keep text readable.
- Left Pane (approx. 60% width): Transparent background, showing the Unity 3D Camera rendering the character model and procedural map.
- Right Pane (approx. 40% width): Frosted glass effect.
- Right-Pane Navigation Bar (Top): Unlike standard top bars, the navigation is contained entirely within the Right Pane.
- [ < Back ] button is pinned to the Top-Left of the right panel.
- [ Settings ] button is pinned to the Top-Right of the right panel.
- Modal Overlay Backdrop: A full-screen VisualElement with a semi-transparent black USS background. Used to dim the screen and block inputs behind the Settings panel, Password Prompts, and Confirmation Dialogs.
2. Screen-by-Screen Implementation Details
2.1. Main Menu (MainMenu.uxml & MainMenuController.cs)
Inspired by osu!lazer, this screen is highly dynamic and relies on smooth, physics-based transitions.
- State 1: Initial Load (Idle)
- Visuals: The background is a heavily blurred, atmospheric map preview. The OS cursor is hidden. Dead center is the Beat Logo.
- Animation: The Beat Logo dynamically pulses (scales up and down) precisely in sync with the audio source's beat/BPM. There are no other UI elements visible.
- State 2: Active Menu (Transition & Active State)
- Interaction: The user moves the mouse toward the center, the logo snaps into focus (glows), and they click.
- Smooth Transition: 1. The Beat Logo shrinks slightly and smoothly translates from the dead center to its designated position in the horizontal menu row.
2. A horizontal VisualElement container (the ribbon) unfolds from behind the logo using an elastic/spring animation.
3. The slanted buttons slide out from the logo's position horizontally: [Settings] to the left, and [Create Room], [Join Room], [Profile], [Exit] to the right. They fade in (opacity: 1) with a staggered C# coroutine delay to create a cascading reveal effect.
2.2. Lobby (Lobby.uxml & LobbyController.cs)
- View Setup: Utilizes the Diagonal Split-Screen Container. The view is dynamic; the Right Pane content switches based on whether the user selected "Join Room" or "Create Room" from the Main Menu.
- Left Pane (Transparent): Shows the player model and live procedural background map generation.
- Right Pane (Static UI Area) - Divided into Two Stages:
- Navigation (Shared): [ < Back ] (Top-Left) and [ Settings ] (Top-Right) are always visible.
- Stage 1: Join Room (Room Browser)
- Triggered when entering via the [Join Room] button.
- Filters & Search: The top of this view includes a TextField for Searching by Room Name, and a DropdownField (or sort icons) for Sorting the list (e.g., by Ping, Name, or Open Slots).
- Room List: A ScrollView dynamically populated with active rooms via C#. Each list item displays the Room Name, Host Name, Ping, and a clear "Lock" icon if the room requires a password.
- Interaction Logic:
- Clicking an unlocked room immediately joins it and transitions the player to the Lounge.
- Clicking a locked room triggers a Modal Overlay popup asking for the password (contains a TextField and [Submit] / [Cancel] buttons) before joining.
- Stage 2: Create Room (Configuration Setup)
- Triggered when entering via the [Create Room] button.
- Content: Dedicated input fields for setting up a new session. Uses TextField for Room Name and an optional Password. Note: Max players is strictly locked to 2, so no dropdown field is necessary.
- Toggles: A "Require password to join" checkbox/toggle is present to enable or disable the password field.
- Action: A large "CREATE ROOM" button sits at the bottom. Clicking this instantiates the room on the server and transitions the player to the Lounge as the Host.
2.3. Profile (Profile.uxml & ProfileController.cs)
- Layout: Reuses the Diagonal Split-Screen structure. The 3D camera shifts to a "Profile Studio" lighting setup for the Left Pane.
- Right Pane Content:
- Navigation: [ < Back ] (Top-Left) and [ Settings ] (Top-Right).
- Header: Player Avatar (circular mask), Username, and Rank/Level badge.
- Statistics: Text labels and progress bars for Win Rate, Matches Played, and current Elo/Rating.
- Customization: A scrollable grid view at the bottom for equipping character skins or banners.
2.4. Lounge / Pre-Match (Lobby.uxml extensions or new UXML)
Since the game is strictly 2-player, the Lounge is an intimate VS screen.
- Layout: The screen is split directly down the middle via a diagonal slash. Player 1 (Host) is on the left, Player 2 (Guest) is on the right.
- Visuals: Each half has a distinctly tinted background color (e.g., Blue for Host, Red/Orange for Guest) behind the transparent 3D character models.
- Navigation: [ < Back ] (Top-Left) and [ Settings ] (Top-Right) overlay the entire screen.
- Confirmation Logic: Clicking [ < Back ] triggers a Modal Overlay popup: "Are you sure you want to leave the room? [Yes] [No]".
- Ready System:
- Bottom of each player's panel has a Ready toggle.
- The Host has a large [ START GAME ] button in the bottom center.
- Logic: The [ START GAME ] button is greyed out (SetEnabled(false)) until both players have toggled their status to "Ready".
2.5. In-Game HUD (MainGameHUD.uxml & HUDController.cs)
The HUD strictly follows a "Zero Obstruction" philosophy with specific interactive zones.
- Area 1: The 3D World (Background)
- The root UI element is fully transparent and set to picking-mode: ignore so all mouse inputs register for aiming/gameplay.
- Area 2: Player Stats (Top Left)
- Visuals: Liquid progress bars for Health and Stamina. Instead of standard flat bars, these utilize a UI Toolkit custom shader or animated sprite mask to look like fluid filling/draining from a container.
- Area 3: Minimap (Top Right)
- Visuals: The minimap continuously updates based on player position. It features a soft fade effect at its borders (achieved via an alpha gradient mask/texture applied to the VisualElement), seamlessly blending it into the gameplay view without harsh square borders.
- Area 4: Inventory (Bottom Left)
- Structure: 4 distinct slots: [ Current Holding ] (larger, highlighted), and three quick-slots [ I ], [ II ], [ III ].
- Logic: Pressing 1, 2, or 3 on the keyboard fires an event in HUDController.cs. The selected item's icon swaps into the [ Current Holding ] slot, and the index updates visually to show what is equipped.
- Area 5: Game Info (Bottom Center)
- Visuals: Minimalist text displaying current Ping (ms) and FPS.
- Auto-Hide Logic:
- To maximize visibility, Area 2 (Stats), Area 4 (Inventory), and Area 5 (Game Info) dynamically fade out.
- In HUDController.cs, track input activity (mouse movement, ability use, damage taken). If Time.time - lastActivityTime > 5f (5 seconds), tween the opacity of these areas to 0 or 0.2. Any new interaction instantly fades them back to 1.
2.6. Settings Menu (Settings.uxml & SettingsController.cs)
- Structure: A floating, centered panel (e.g., occupies roughly 60% width and 70% height) rather than a full-screen view. It sits on top of a full-screen semi-transparent backdrop that blocks interactions with the underlying UI.
- Global Shortcut: The Settings menu can be toggled open or closed from anywhere in the game by pressing Ctrl + O.
- Visuals: The panel has rounded corners and distinct styling to elevate it from the background.
- Layout: Standard settings configuration (Audio sliders, Graphics toggles) using UI Toolkit elements, with a prominent [ X Close ] button in the top right corner of the panel.
3. C# State Machine & Routing Logic (UIManager.cs)
To manage UXML templates, UIManager.cs controls the flow using a stack-based approach.
[Game Launch]
|
[Main Menu (Idle -> Active Logo Bar)]
|
+-------------------+-------------------+-------------------+
| | | |
v v v v
[Lobby: Create] [Lobby: Join] [Profile] [Settings (Overlay)]
| | | |
v v | |
[Lounge (Host)] [Lounge (Guest)] +---(Back)----------+
| |
+--- [All Ready] ---+
|
(Host Clicks Start)
|
v
[IN-GAME HUD]
UI Toolkit State Management Implementation
- Screen Controller Pattern: Each controller (MainMenuController, LobbyController, etc.) holds a reference to its root VisualElement defined in its corresponding .uxml file.
- Navigation Stack (Stack<VisualElement>): UIManager.cs pushes screens to this stack. Pressing the Top-Left [ < Back ] button calls a method to pop the current state, hiding it (display: none) and showing the previous one (display: flex).
- Global Action Listeners (Ctrl + O): UIManager.cs actively listens to the input system for Ctrl + O to instantly trigger SettingsController.ToggleSettings() without affecting the current navigation stack path.
- Cursorless Input Routing: UIManager.cs constantly monitors Input.mousePosition. It calculates the nearest interactive element within the active screen and applies a .hover USS class to it, overriding default Unity pointer events.