165 lines
3.6 KiB
Markdown
165 lines
3.6 KiB
Markdown
# Card UI Standardization
|
|
|
|
## Goal
|
|
|
|
Make every card-shaped UI use the same input structure so hover tooltip,
|
|
click, drag, and future interactions behave the same way everywhere.
|
|
|
|
Target surfaces:
|
|
|
|
- hand cards
|
|
- reward cards
|
|
- shop cards
|
|
- draw pile / discard pile / exhaust pile viewer cards
|
|
- all deck / class deck / codex cards
|
|
|
|
## Standard Card Entity Shape
|
|
|
|
Each visible card should have one root entity that owns input.
|
|
|
|
```text
|
|
CardRoot
|
|
- UITransformComponent
|
|
- SpriteGUIRendererComponent
|
|
- ButtonComponent
|
|
- UITouchReceiveComponent
|
|
- Cost
|
|
- Name
|
|
- Desc
|
|
- Art
|
|
```
|
|
|
|
Rules:
|
|
|
|
1. `CardRoot` covers the full card rect.
|
|
2. `CardRoot` owns both click and hover.
|
|
3. Child entities are display only.
|
|
4. Child entities must not become the primary input target.
|
|
|
|
## Required Component Rules
|
|
|
|
### Card root
|
|
|
|
- `UITransformComponent`
|
|
- `SpriteGUIRendererComponent`
|
|
- `ButtonComponent`
|
|
- `UITouchReceiveComponent`
|
|
|
|
Recommended sprite settings:
|
|
|
|
- `RaycastTarget: true`
|
|
- card frame sprite on root
|
|
|
|
### Card children
|
|
|
|
- `Cost`, `Name`, `Desc`: text only
|
|
- `Art`: sprite only
|
|
|
|
Recommended child sprite settings:
|
|
|
|
- `RaycastTarget: false`
|
|
|
|
That keeps hover/click ownership on the root card entity.
|
|
|
|
## Path Rules
|
|
|
|
Use the same path naming pattern everywhere:
|
|
|
|
- hand: `/ui/.../CardHand/Card1`
|
|
- reward: `/ui/.../RewardHud/Reward1`
|
|
- shop: `/ui/.../ShopHud/Card1`
|
|
- inspect: `/ui/.../DeckInspectHud/Grid/Card1`
|
|
- all deck: `/ui/.../DeckAllHud/Grid/Card1`
|
|
|
|
The important part is that each list has a stable root card path ending in a
|
|
numeric slot. That lets controller code resolve hover target -> slot -> card id
|
|
without special cases.
|
|
|
|
## Controller Rules
|
|
|
|
Once UI is standardized, controller logic should follow this shape:
|
|
|
|
1. Resolve `path`
|
|
2. Resolve `slot` from `path`
|
|
3. Resolve `cardId` from current backing list
|
|
4. Show tooltip from `cardId`
|
|
|
|
Preferred shared methods:
|
|
|
|
- `GetHoveredCardId(path)`
|
|
- `HoverCardByPath(path)`
|
|
- `UnhoverCardByPath(path)`
|
|
|
|
The hand should just become one caller of the same shared path-based hover
|
|
logic rather than having its own special tooltip flow.
|
|
|
|
## Safe Rollout Order
|
|
|
|
Do not standardize every card surface at once.
|
|
|
|
### Step 1
|
|
|
|
Document current structures for:
|
|
|
|
- `RewardHud/Reward1`
|
|
- `ShopHud/Card1`
|
|
- `DeckInspectHud/Grid/Card1`
|
|
- `DeckAllHud/Grid/Card1`
|
|
|
|
### Step 2
|
|
|
|
Make `DeckInspectHud/Grid/CardN` match `RewardHud/RewardN` component structure.
|
|
|
|
### Step 3
|
|
|
|
Verify game boot and UI load before changing controller hover bindings.
|
|
|
|
### Step 4
|
|
|
|
Make `DeckAllHud/Grid/CardN` match the same structure.
|
|
|
|
### Step 5
|
|
|
|
After both surfaces are stable, bind hover events in controller code.
|
|
|
|
## Validation Checklist
|
|
|
|
Before testing hover behavior:
|
|
|
|
- game boots with no `LEA-3015 CannotLoad`
|
|
- `DefaultGroup.ui` loads cleanly
|
|
- card roots exist at expected paths
|
|
- root card sprite has `RaycastTarget: true`
|
|
- child art sprite has `RaycastTarget: false`
|
|
- root has both `ButtonComponent` and `UITouchReceiveComponent`
|
|
|
|
After binding hover:
|
|
|
|
- hand tooltip still works
|
|
- reward tooltip still works
|
|
- shop tooltip still works
|
|
- inspect tooltip works
|
|
- all deck tooltip works
|
|
- no duplicated tooltip flicker
|
|
- no drag regression on hand cards
|
|
|
|
## What Not To Do
|
|
|
|
- do not hand-edit `ui/DefaultGroup.ui`
|
|
- do not change multiple card surfaces in one shot
|
|
- do not mix root-input cards with child-input cards
|
|
- do not add hover logic before confirming the target card entity actually
|
|
receives input
|
|
|
|
## Recommended Next Change
|
|
|
|
The next implementation step should be:
|
|
|
|
1. diff `DeckInspectHud/Grid/Card1` against `RewardHud/Reward1`
|
|
2. make only `DeckInspectHud` root card structure match
|
|
3. regenerate UI
|
|
4. boot test
|
|
5. then bind hover for inspect cards only
|
|
|
|
That keeps the blast radius small.
|