Cleanup the card implementation, add some readme files and update namespaces
This commit is contained in:
194
docs/ui_page_navigation.md
Normal file
194
docs/ui_page_navigation.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# UI Page Navigation System
|
||||
|
||||
A brief guide to the stack-based page navigation used across the project. It is built around `UIPageController` (the navigator) and `UIPage` (the base page with transition hooks). This system is used by the card collection UI and can be reused for any feature that needs push/pop navigation with transitions.
|
||||
|
||||
- Source files:
|
||||
- `Assets/Scripts/UI/Core/UIPageController.cs`
|
||||
- `Assets/Scripts/UI/Core/UIPage.cs`
|
||||
|
||||
## Table of Contents
|
||||
- [Concepts](#concepts)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Transitions and Events](#transitions-and-events)
|
||||
- [Card System Case Studies](#card-system-case-studies)
|
||||
- [Best Practices](#best-practices)
|
||||
- [API Reference (Essentials)](#api-reference-essentials)
|
||||
|
||||
## Concepts
|
||||
- `UIPageController`
|
||||
- A singleton navigator that maintains a stack of `UIPage` instances.
|
||||
- Provides `PushPage`, `PopPage`, and `ClearStack`.
|
||||
- Fires `OnPageChanged` when the top page changes.
|
||||
- `UIPage`
|
||||
- Base class for pages with overridable transition hooks.
|
||||
- Implements `TransitionIn`, `TransitionOut`, and `OnBackPressed`.
|
||||
- Comes with start/complete events for both in/out transitions.
|
||||
|
||||
Stack behavior in short:
|
||||
- `PushPage(page)` hides the current page (transition out), shows the new page (transition in), and puts it on top.
|
||||
- `PopPage()` hides the current page (transition out), reveals the previous top page (transition in).
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1) Showing a page
|
||||
```csharp
|
||||
// Assuming you have a reference to a concrete UIPage (via scene object or instantiated prefab)
|
||||
[SerializeField] private UIPage albumViewPage;
|
||||
|
||||
void OpenAlbum()
|
||||
{
|
||||
UIPageController.Instance.PushPage(albumViewPage);
|
||||
}
|
||||
```
|
||||
|
||||
### 2) Going back
|
||||
```csharp
|
||||
void Back()
|
||||
{
|
||||
UIPageController.Instance.PopPage();
|
||||
}
|
||||
```
|
||||
|
||||
### 3) Custom page with simple transitions
|
||||
```csharp
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class FadePage : UIPage
|
||||
{
|
||||
[SerializeField] private CanvasGroup canvasGroup;
|
||||
|
||||
protected override void DoTransitionIn(Action onComplete)
|
||||
{
|
||||
// Example: simple fade in (pseudo-code; replace with your tween/anim system)
|
||||
canvasGroup.alpha = 0f;
|
||||
gameObject.SetActive(true);
|
||||
// Tween to alpha 1 over transitionDuration, then:
|
||||
onComplete?.Invoke();
|
||||
}
|
||||
|
||||
protected override void DoTransitionOut(Action onComplete)
|
||||
{
|
||||
// Example: simple fade out
|
||||
// Tween to alpha 0 over transitionDuration, then:
|
||||
onComplete?.Invoke();
|
||||
// The base class will SetActive(false) after completion.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4) Wiring a generic Cancel/Back input (optional)
|
||||
`UIPageController` has placeholders to wire a Cancel action from the Input System. If you want a global back action:
|
||||
```csharp
|
||||
// In your bootstrap or scene initializer
|
||||
var controller = UIPageController.Instance; // ensure it exists in the scene
|
||||
// Optionally hook up your own input and call:
|
||||
if (controller.CurrentPage != null)
|
||||
{
|
||||
controller.CurrentPage.OnBackPressed();
|
||||
}
|
||||
```
|
||||
|
||||
## Transitions and Events
|
||||
|
||||
`UIPage` exposes these events:
|
||||
- `OnTransitionInStarted`
|
||||
- `OnTransitionInCompleted`
|
||||
- `OnTransitionOutStarted`
|
||||
- `OnTransitionOutCompleted`
|
||||
|
||||
Use them to coordinate animation, audio, or deferred loading.
|
||||
|
||||
Example: enable input only after a page is visible.
|
||||
```csharp
|
||||
void OnEnable()
|
||||
{
|
||||
albumViewPage.OnTransitionInCompleted += EnableAlbumInput;
|
||||
albumViewPage.OnTransitionOutStarted += DisableAlbumInput;
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
albumViewPage.OnTransitionInCompleted -= EnableAlbumInput;
|
||||
albumViewPage.OnTransitionOutStarted -= DisableAlbumInput;
|
||||
}
|
||||
```
|
||||
|
||||
## Card System Case Studies
|
||||
|
||||
These examples show how the card UI uses the page stack.
|
||||
|
||||
### Open the Card Menu from gameplay HUD
|
||||
```csharp
|
||||
[SerializeField] private UIPage cardMenuPage;
|
||||
|
||||
public void OnBackpackButton()
|
||||
{
|
||||
UIPageController.Instance.PushPage(cardMenuPage);
|
||||
}
|
||||
```
|
||||
|
||||
### Navigate from Card Menu to Album view
|
||||
```csharp
|
||||
[SerializeField] private UIPage albumViewPage;
|
||||
|
||||
public void OnAlbumButton()
|
||||
{
|
||||
UIPageController.Instance.PushPage(albumViewPage);
|
||||
}
|
||||
```
|
||||
|
||||
### Enter Booster Opening flow and then return
|
||||
```csharp
|
||||
[SerializeField] private UIPage boosterOpeningPage;
|
||||
|
||||
public void OnOpenBooster()
|
||||
{
|
||||
// Assume booster count was verified via `CardSystemManager`
|
||||
UIPageController.Instance.PushPage(boosterOpeningPage);
|
||||
}
|
||||
|
||||
// Inside the booster opening page, when user taps Back or after completion
|
||||
public override void OnBackPressed()
|
||||
{
|
||||
if (!_isTransitioning)
|
||||
{
|
||||
// Optional: guard against leaving mid-reveal
|
||||
// if (!revealComplete) return;
|
||||
UIPageController.Instance.PopPage();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Close all card UI and return to HUD
|
||||
```csharp
|
||||
public void CloseAllCardUI()
|
||||
{
|
||||
UIPageController.Instance.ClearStack();
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
- One active `UIPageController` per UI context (usually one in the main UI scene). Avoid multiple competing controllers.
|
||||
- Keep transitions short and responsive; the base class already handles `SetActive` lifecycle for you.
|
||||
- Always check `_isTransitioning` (available in `UIPage`) before triggering back/forward actions to avoid double navigations.
|
||||
- Use `OnPageChanged` on `UIPageController` to manage global state (e.g., pause input when a modal page is shown).
|
||||
- If you instantiate pages at runtime, ensure their `GameObject` is inactive by default and let `TransitionIn` activate them.
|
||||
|
||||
## API Reference (Essentials)
|
||||
|
||||
From `UIPageController`:
|
||||
- `UIPage CurrentPage` — top of the stack or `null`.
|
||||
- `event Action<UIPage> OnPageChanged` — fired after a push/pop resolves.
|
||||
- `void PushPage(UIPage page)` — transitions out current (if any), transitions in the new page, pushes it on the stack.
|
||||
- `void PopPage()` — transitions out current, reveals previous page with a transition in.
|
||||
- `void ClearStack()` — transitions out current and empties the stack.
|
||||
|
||||
From `UIPage`:
|
||||
- `string PageName` — a designer-friendly name for logs/diagnostics.
|
||||
- `float transitionDuration` (protected) — your animations can use this.
|
||||
- `virtual void TransitionIn()` / `TransitionOut()` — call the overridable `DoTransitionIn`/`DoTransitionOut`.
|
||||
- `virtual void OnBackPressed()` — default pops the page (calls `UIPageController.Instance.PopPage()`). Override to customize.
|
||||
- Events: `OnTransitionInStarted`, `OnTransitionInCompleted`, `OnTransitionOutStarted`, `OnTransitionOutCompleted`.
|
||||
|
||||
For additional context and examples, see `docs/card_system_playbook.md` and `docs/card_system_integration_and_testing.md`.
|
||||
Reference in New Issue
Block a user