UI Polish + Fixes Plan (2026-07-03)¶
Batch of fixes/features on top of the missing-UI work. Ordered; commit per group.
1. Result loot crash (CRITICAL) — ResultScreenView.RenderLoot¶
MissingComponentException at cg.alpha: GetComponent<CanvasGroup>() ?? AddComponent<...>()
— the ?? operator bypasses Unity's fake-null override, returning a missing component.
Fix: explicit var cg = GetComponent<CanvasGroup>(); if (cg == null) cg = AddComponent<...>();.
2. Map markers (MapView / MapController / MapMarker)¶
- Flat crisp circle — current
Circle()fades RGB centre→rim, which reads as a gradient. Make a flat solid disc (uniform colour, hard AA edge) + a thin constant dark outline ring. Shared static sprite → affects minimap AND full map (verify the minimap actually re-renders). - Zoomed marker size —
Renderusesm.Size * _dotScale(fixed). When zoomed (vp.SpanUV < 1) scale dots up by1/span(fit-all = 1×, zoom 0.5 = 2×) so they grow with the map. - Pulsing markers — add
bool PulsetoMapMarker.RebuildMarkerssets it on portals (descent + open exits) and boss enemies (the "portal guard").MapView.Renderapplies a time-based sine size pulse to pulsing markers AND always to the player dot (web player blip).
3. Settings vibration toggle disabled marker (UIToggle)¶
Add [SerializeField] GameObject disabledMark; shown when OFF (mirrors the slider's 0 mark).
Wire the vibration row's img_disabled to the vibration UIToggle.
4. Unified player Power (single source of truth)¶
Lobby / inventory / equipment / in-raid top panels show different Power. Create one helper
GearStats-based compute (saved loadout, else starter kit) and route every top-panel Power through
it: LobbyController.PlayerPower, InventoryController (equipment + inventory top panels),
in-raid HUD (RaidState.PlayerPower is set on spawn from the same source — confirm it matches).
Find all .power/Power readouts and unify.
5. UIButton two-step confirm mode (reusable)¶
Add an opt-in confirm state:
- SetConfirm(bool required, float cooldown = -1f) + optional [SerializeField] TMP_Text label.
- First click (when required & not awaiting) → label → "Confirm?", become the single global
pending-confirm button (entering confirm on ANY button resets the previous one = "different click"
resets). cooldown >= 0 auto-resets after that many unscaled seconds; default -1 = no auto-reset.
- OnDisable/re-show resets (view reopen).
- Second click (awaiting) → reset + fire Clicked.
Apply to:
- Settings Delete — always confirm → SettingsController wipes the save (ISaveService.Wipe) + reloads.
- Item-card Scrap — confirm when the item is better-than-current OR equipped (equipped
always confirms). InventoryController/card sets scrapButton.SetConfirm(required) per item.
6. Wire Settings Delete (ITEM 5 dependency)¶
SettingsView expose DeleteClicked (btn_delete UIButton, confirm-mode) → SettingsController
→ _save.Wipe() + scene reload.
Commit groups¶
- crash fix · 2. map markers (flat circle + zoom size + pulse) · 3. toggle disabled mark ·
- UIButton confirm + settings delete · 5. scrap confirm · 6. unified power.