From 72dad1ce4c2223341647bed20598db6f76325133 Mon Sep 17 00:00:00 2001 From: jongjae Date: Fri, 29 May 2026 00:53:49 +0900 Subject: [PATCH] docs: update project handoff --- CLAUDE_REVIEW_HUD_PROPOSAL.md | 18 +++ COLLABORATION_RULES.md | 8 +- HANDOFF.md | 236 ++++++++++++++++++---------------- 3 files changed, 149 insertions(+), 113 deletions(-) diff --git a/CLAUDE_REVIEW_HUD_PROPOSAL.md b/CLAUDE_REVIEW_HUD_PROPOSAL.md index 8e18587..7cc25eb 100644 --- a/CLAUDE_REVIEW_HUD_PROPOSAL.md +++ b/CLAUDE_REVIEW_HUD_PROPOSAL.md @@ -1,5 +1,23 @@ # Claude Review Request: Game Scene HUD Polish +## Status + +This proposal has mostly been implemented and superseded by the current UI-quality pass. + +Implemented since this proposal: + +- ScoreCanvas was moved closer to the player. +- Left/right HUD structure was created. +- Multiplier ring background and song progress bar were added. +- Song current time / total time is displayed. +- Result screen polish has become the current priority. + +Remaining HUD follow-up: + +- Verify HUD readability in Play Mode. +- Consider migrating HUD labels from legacy `UI.Text` to TMP after the result screen is stable. +- Add rank/multiplier micro animations only after static layout is approved. + ## Goal Match the Game scene HUD closer to the provided Beat Saber-style reference: diff --git a/COLLABORATION_RULES.md b/COLLABORATION_RULES.md index 196153a..67aecb2 100644 --- a/COLLABORATION_RULES.md +++ b/COLLABORATION_RULES.md @@ -17,4 +17,10 @@ When changing code in this project, Codex and Claude Code should use a mutual re ## Current User Preference -For now, focus on polishing the Unity Game scene. Do not change code unless the review gate above is satisfied. +Current quality focus: + +1. Polish the result screen UI first. +2. Then polish the in-game HUD. +3. Then consider song select UI. + +Do not change code unless the review gate above is satisfied. diff --git a/HANDOFF.md b/HANDOFF.md index d6c20a5..fcf0ba4 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,112 +1,97 @@ -# VR Beat Saber 프로젝트 인수인계 +# VR Beat Saber Handoff -## 현재 상태 +## Project Status - Unity: `6000.3.12f1` -- 브랜치: `master` -- 원격 저장소: `origin = https://whdwo798.synology.me/whdwo798/BeatSaber.git` -- 현재 주요 작업 초점: `Assets/Scenes/Game.unity` 게임 화면, HUD, 점수/랭크, 결과 화면, 노트 체감 개선 +- Branch: `master` +- Remote: `origin = https://whdwo798.synology.me/whdwo798/BeatSaber.git` +- Latest pushed commit before this document update: `fb59fc3 feat: polish result screen UI` +- Current focus: raise overall UI quality, starting from the result screen, then HUD, then song select. -## 협업 규칙 +## Collaboration Rule -- 코드 변경 전 Codex와 Claude Code가 변경 방향을 서로 검토한다. -- 100점 만점 기준 80점 이상이면 진행한다. -- 세부 규칙은 `COLLABORATION_RULES.md`에 정리되어 있다. +- Code changes should go through a Codex and Claude Code mutual review gate. +- A proposal should score at least 80/100 before implementation. +- Review criteria: + - Correctness + - Scope control + - Unity scene/runtime risk + - Maintainability + - Verification plan -## Unity / MCP 브릿지 +See `COLLABORATION_RULES.md`. + +## Unity / MCP Bridge - `Assets/Editor/UnityCodexBridgeServer.cs` - - 기본 포트 충돌 시 `19744-19748` 범위에서 fallback 하도록 수정했다. + - Bridge now falls back across ports `19744-19748` when the default port is busy. - `tools/unity-mcp-server/index.mjs` - - `UNITY_BRIDGE_URL`이 없으면 Unity 브릿지 포트를 자동 탐색한다. -- 최근 사용 포트는 `19745`였다. -- Unity 로그에는 `Cannot find parent for ...` / UIElements RenderChain 로그가 반복될 수 있는데, 현재 확인된 범위에서는 게임 코드 컴파일 오류가 아니라 에디터 UI 쪽 로그로 보인다. + - MCP server probes the same fallback port range when `UNITY_BRIDGE_URL` is not explicitly set. +- This was added because Unity reported that the bridge socket address was already in use. -## Game 씬 HUD +## Game Scene HUD -### ScoreCanvas 배치 +### ScoreCanvas Placement `Assets/Scenes/Game.unity` -- `ScoreCanvas` 위치를 플레이어 앞쪽으로 당겼다. +- `ScoreCanvas` was moved closer to the player: - Z: `17.8 -> 5` - Scale: `0.005 -> 0.006` - `applyHudPlacement`: `true -> false` -- HUD가 중앙에 겹치던 문제를 줄이고, 좌우로 분리되어 보이게 했다. +- This prevents HUD elements from collapsing visually near the center of the tunnel. -### ScoreManager HUD 생성/배치 +### Runtime HUD `Assets/VRBeatsKit/Scripts/UI/ScoreManager.cs` -- 왼쪽 HUD: - - `COMBO` - - score - - accuracy - - rank -- 오른쪽 HUD: - - multiplier text - - multiplier ring background - - song progress bar - - current time / total time -- 동적 생성 Text에는 `LegacyRuntime.ttf`를 lazy 로딩해서 폰트가 비어 렌더링되지 않는 문제를 막았다. -- `Resources.GetBuiltinResource`는 static initializer에서 호출하지 않도록 수정했다. -- 진행 바는 `Image.fillAmount` 대신 RectTransform 폭을 직접 조절해서 더 안정적으로 표시한다. +- Left HUD: + - Combo + - Score + - Accuracy + - Current rank +- Right HUD: + - Multiplier value + - Multiplier ring and faint ring background + - Song progress bar + - Current time / total time +- Dynamic legacy `Text` labels lazily load `LegacyRuntime.ttf` to avoid missing-font rendering issues. +- The progress bar fills from `0 -> 1` as the song progresses. -## 노래 시간 / 완료 처리 +## Timing / Completion `Assets/VRBeatsKit/Scripts/Core/AudioManager.cs` -- `AudioSource.time` 접근 시 Unity가 `resource that is not a clip` 경고를 내던 문제를 피하기 위해 DSP 기반 시간을 우선 사용한다. +- Song time now uses scheduled DSP time instead of reading `AudioSource.time`. +- This avoids the Unity warning about requesting `time` from an audio source whose resource is not a clip. `Assets/Script/SongController.cs` -- MP3 `clip.length`가 0으로 잡힐 때를 대비해 fallback duration을 계산한다. - - `song.duration` - - 마지막 노트 시간 + 1초 -- 결과 완료 대기에는 `clip.length`가 아니라 `_clipLength`를 사용한다. -- 이 수정으로 게임 도중 갑자기 결과창이 뜨는 문제를 줄였다. - -## 노트 위치 체감 - -`Assets/Script/SongController.cs` - -- 낮은 큐브가 너무 바닥에 깔려 베기 어려운 문제를 줄였다. -- Y 레이어 매핑 변경: +- Song duration falls back to metadata or last note time when `clip.length` is zero. +- Completion waits until the last note / known duration instead of ending early because of a bad clip length. +- Note layer Y positions were raised so low notes are easier to slice: ```text -이전: -lineLayer 0: -0.38 -lineLayer 1: 0.00 -lineLayer 2: +0.38 - -현재: lineLayer 0: -0.12 lineLayer 1: +0.22 lineLayer 2: +0.56 ``` -- 적용값: - -```csharp -private const float LayerSpacing = 0.34f; -private const float VerticalOffset = 0.22f; -``` - -## 점수 / 랭크 / 콤보 배율 +## Scoring / Rank Rules `Assets/VRBeatsKit/Scripts/UI/ScoreManager.cs` -### 점수 구조 - -- 총점 최대: `1,000,000` -- 정확도 점수: `800,000` -- 콤보 보너스: `200,000` +### Score Formula ```text CurrentScore = 800000 * accuracyRatio + 200000 * comboRatio ``` -### 판정 가중치 +- Max score: `1,000,000` +- Accuracy contribution: `800,000` +- Max combo contribution: `200,000` + +### Judgement Points ```text Perfect = 1000 @@ -115,7 +100,7 @@ Good = 700 Miss = 0 ``` -### 판정 시간 +### Timing Windows ```text Perfect <= 0.11s @@ -123,24 +108,22 @@ Great <= 0.20s Good <= 0.32s ``` -### 콤보 배율 +### Combo Multiplier -초보자도 빨리 보상을 느끼도록 조정했다. +The multiplier is intentionally beginner-friendly: ```text -0~4 combo x1.0 -5~14 combo x1.1 -15~29 combo x1.2 -30~49 combo x1.35 +0-4 combo x1.0 +5-14 combo x1.1 +15-29 combo x1.2 +30-49 combo x1.35 50+ combo x1.5 ``` -Multiplier ring 진행도도 같은 구간 기준으로 맞췄다. +### Rank Thresholds -### 랭크 - -- `M`: 최종 점수 `1,000,000` 이상 -- 그 외 랭크는 `AccuracyPercent` 기준 +- `M`: final score `>= 1,000,000` +- Other ranks use `AccuracyPercent`: ```text S+ >= 98% @@ -152,12 +135,12 @@ D >= 60% F < 60% ``` -### 랭크 색상 +### Rank Colors ```text -M #E8B7FF 보석/프리즘 느낌 -S+ #41F2FF 청록 네온 -S #FFD95C 골드 +M #E8B7FF prism / jewel tone +S+ #41F2FF cyan neon +S #FFD95C gold A #B9FF72 B #FFE06A C #FFB15C @@ -165,56 +148,85 @@ D #FF7C7C F #A9B7C0 ``` -## 결과 화면 +## Result Screen `Assets/VRBeatsKit/Scripts/UI/FinalScoreLabel.cs` -- 기존 `scoreText` 하나에 rich text로 모든 결과를 넣는 방식에서, 결과 전용 레이아웃을 런타임 생성하는 방식으로 변경했다. -- `ShowScore()`에서 기존 `Title`을 숨기고, 원래 `scoreText`를 비활성화한 뒤 결과 전용 레이아웃을 보여준다. -- `ResetValues()`에서 결과 레이아웃을 숨기고 `Title`과 `scoreText`를 복원한다. +The result screen is now the first major UI-quality target. -동적 생성 구조: +Current result layout is generated at runtime: ```text ResultLayoutRoot - ├── RankShadowText - ├── RankDepthText - ├── RankMainText - ├── ResultScoreText - └── ResultComboText + RankShadowText + RankDepthText + RankMainText + ResultScoreText + ResultAccuracyText + ResultComboText ``` -- `RankShadowText`, `RankDepthText`, `RankMainText`를 겹쳐 랭크가 더 입체적으로 보이도록 했다. -- `scoreText.font`와 `scoreText.fontSharedMaterial`을 복사해서 런타임 생성 TMP가 렌더링되지 않는 문제를 방지했다. -- `M`은 연보라 main + 시안 depth로 보석 느낌을 주고, `S+`는 청록, `S`는 골드 계열로 구분한다. +Implemented: -## 비주얼 / 세이버 / 파티클 +- Existing `Title` is hidden while result content is shown. +- Existing serialized `scoreText` is hidden and used as a font/material source. +- Rank uses layered TMP text for a more dimensional badge. +- Result info now shows: + - `SCORE` + - final score + - `ACCURACY` + - max combo +- Result popup and restart/back buttons were tinted toward a darker translucent cyan UI style. -### 파란색 가시성 +Known follow-up: + +- `tmp.lineSpacing = -8.0f` is aggressive and may need visual tuning if the `SCORE` label overlaps the score value. +- Button styling is improved by color, but does not yet have a dedicated neon border/glow treatment. +- The scene appears to contain both result and game-over popup/button sets; verify that shared color changes are intentional. + +## Visual Effects + +Blue visibility improvements were made in: - `Assets/VRBeatsKit/Settings/Settings.asset` - `Assets/VRBeatsKit/Scripts/Core/SaberTrailEffect.cs` - `Assets/VRBeatsKit/Scripts/Core/SliceTrailEffect.cs` - `Assets/VRBeatsKit/Scripts/Other/Spark.cs` -파란색 세이버/트레일/스파크가 너무 연해서 잘 보이지 않던 문제를 줄였다. +Goal: -### 결과 팝업 / 사버 표시 +- Keep red strong. +- Make blue saber/trail/spark readable against the bright cyan tunnel. -- 게임오버/결과 시 세이버 표시 상태를 정리해 결과 화면이 더 읽기 쉽도록 했다. +## UI Quality Direction -## 주의 사항 +Current agreed direction: -- `dotnet build`는 Unity 패키지 참조를 일반 .NET 빌드가 못 찾는 경우가 있어 신뢰도가 낮다. Unity 에디터 컴파일 로그와 Play 모드 확인을 우선한다. -- `Library/ScriptAssemblies/Assembly-CSharp.dll` timestamp가 갱신되지 않으면 Unity가 아직 스크립트를 리로드하지 않은 상태일 수 있다. -- 결과 화면 레이아웃은 실제 Play 화면에서 `M`, `S+`, `1,000,000`, 긴 `MAX COMBO` 케이스로 크기/위치를 확인해야 한다. -- Unity Console의 UIElements RenderChain 로그는 현재 작업한 게임 코드와 직접 연관된 컴파일 오류로 보이지 않는다. +1. Finish result screen polish first. +2. Then polish in-game HUD. +3. Then consider HUD migration from legacy `UI.Text` to TMP for sharper VR rendering. +4. Then redesign song select cards/details. -## 다음 확인 권장 +Design principles: -1. Game 씬 Play 후 HUD 좌우 위치 확인 -2. 시간바가 실제 노래 시간에 따라 차오르는지 확인 -3. 노래가 중간에 조기 종료되지 않는지 확인 -4. 낮은 큐브가 베기 편해졌는지 VR에서 확인 -5. 결과 화면에서 `M/S+/S/F` 등급 배지의 크기, 위치, 색상 확인 -6. `M` 달성 조건이 의도대로 최종 100만점일 때만 뜨는지 확인 +- Thin readable text. +- Dark translucent panels, not heavy opaque boxes. +- White/cyan baseline UI with rank color accents. +- Large values, small labels. +- Avoid clutter in the note highway. +- Add micro animations only after the static layout is readable. + +## Verification Notes + +- `git diff --check` passed for the latest result UI changes. +- `dotnet build beatSaber.slnx --no-incremental` is not reliable for this Unity project in the current environment because regular .NET build cannot resolve many Unity/TMP/UI/XR assemblies. +- Prefer Unity Editor compile and Play Mode for final verification. + +## Recommended Next Checks + +1. Play the Game scene and finish a song. +2. Check result screen layout for `M`, `S+`, `S`, and `F`. +3. Verify score, accuracy, and max combo do not overlap. +4. Confirm Restart and Back buttons remain clickable. +5. Check whether result popup and game-over popup color changes should both stay. +6. If result screen is stable, move to HUD polish and TMP migration discussion.