docs: update project handoff
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
+124
-112
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user