Files
BeatSaber/HANDOFF.md
T

6.6 KiB

VR Beat Saber 프로젝트 인수인계

현재 상태

  • Unity: 6000.3.12f1
  • 브랜치: master
  • 원격 저장소: origin = https://whdwo798.synology.me/whdwo798/BeatSaber.git
  • 현재 주요 작업 초점: Assets/Scenes/Game.unity 게임 화면, HUD, 점수/랭크, 결과 화면, 노트 체감 개선

협업 규칙

  • 코드 변경 전 Codex와 Claude Code가 변경 방향을 서로 검토한다.
  • 100점 만점 기준 80점 이상이면 진행한다.
  • 세부 규칙은 COLLABORATION_RULES.md에 정리되어 있다.

Unity / MCP 브릿지

  • Assets/Editor/UnityCodexBridgeServer.cs
    • 기본 포트 충돌 시 19744-19748 범위에서 fallback 하도록 수정했다.
  • tools/unity-mcp-server/index.mjs
    • UNITY_BRIDGE_URL이 없으면 Unity 브릿지 포트를 자동 탐색한다.
  • 최근 사용 포트는 19745였다.
  • Unity 로그에는 Cannot find parent for ... / UIElements RenderChain 로그가 반복될 수 있는데, 현재 확인된 범위에서는 게임 코드 컴파일 오류가 아니라 에디터 UI 쪽 로그로 보인다.

Game 씬 HUD

ScoreCanvas 배치

Assets/Scenes/Game.unity

  • ScoreCanvas 위치를 플레이어 앞쪽으로 당겼다.
    • Z: 17.8 -> 5
    • Scale: 0.005 -> 0.006
    • applyHudPlacement: true -> false
  • HUD가 중앙에 겹치던 문제를 줄이고, 좌우로 분리되어 보이게 했다.

ScoreManager 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 폭을 직접 조절해서 더 안정적으로 표시한다.

노래 시간 / 완료 처리

Assets/VRBeatsKit/Scripts/Core/AudioManager.cs

  • AudioSource.time 접근 시 Unity가 resource that is not a clip 경고를 내던 문제를 피하기 위해 DSP 기반 시간을 우선 사용한다.

Assets/Script/SongController.cs

  • MP3 clip.length가 0으로 잡힐 때를 대비해 fallback duration을 계산한다.
    • song.duration
    • 마지막 노트 시간 + 1초
  • 결과 완료 대기에는 clip.length가 아니라 _clipLength를 사용한다.
  • 이 수정으로 게임 도중 갑자기 결과창이 뜨는 문제를 줄였다.

노트 위치 체감

Assets/Script/SongController.cs

  • 낮은 큐브가 너무 바닥에 깔려 베기 어려운 문제를 줄였다.
  • Y 레이어 매핑 변경:
이전:
lineLayer 0: -0.38
lineLayer 1:  0.00
lineLayer 2: +0.38

현재:
lineLayer 0: -0.12
lineLayer 1: +0.22
lineLayer 2: +0.56
  • 적용값:
private const float LayerSpacing = 0.34f;
private const float VerticalOffset = 0.22f;

점수 / 랭크 / 콤보 배율

Assets/VRBeatsKit/Scripts/UI/ScoreManager.cs

점수 구조

  • 총점 최대: 1,000,000
  • 정확도 점수: 800,000
  • 콤보 보너스: 200,000
CurrentScore = 800000 * accuracyRatio + 200000 * comboRatio

판정 가중치

Perfect = 1000
Great   = 900
Good    = 700
Miss    = 0

판정 시간

Perfect <= 0.11s
Great   <= 0.20s
Good    <= 0.32s

콤보 배율

초보자도 빨리 보상을 느끼도록 조정했다.

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 진행도도 같은 구간 기준으로 맞췄다.

랭크

  • M: 최종 점수 1,000,000 이상
  • 그 외 랭크는 AccuracyPercent 기준
S+ >= 98%
S  >= 95%
A  >= 90%
B  >= 80%
C  >= 70%
D  >= 60%
F  < 60%

랭크 색상

M   #E8B7FF  보석/프리즘 느낌
S+  #41F2FF  청록 네온
S   #FFD95C  골드
A   #B9FF72
B   #FFE06A
C   #FFB15C
D   #FF7C7C
F   #A9B7C0

결과 화면

Assets/VRBeatsKit/Scripts/UI/FinalScoreLabel.cs

  • 기존 scoreText 하나에 rich text로 모든 결과를 넣는 방식에서, 결과 전용 레이아웃을 런타임 생성하는 방식으로 변경했다.
  • ShowScore()에서 기존 Title을 숨기고, 원래 scoreText를 비활성화한 뒤 결과 전용 레이아웃을 보여준다.
  • ResetValues()에서 결과 레이아웃을 숨기고 TitlescoreText를 복원한다.

동적 생성 구조:

ResultLayoutRoot
  ├── RankShadowText
  ├── RankDepthText
  ├── RankMainText
  ├── ResultScoreText
  └── ResultComboText
  • RankShadowText, RankDepthText, RankMainText를 겹쳐 랭크가 더 입체적으로 보이도록 했다.
  • scoreText.fontscoreText.fontSharedMaterial을 복사해서 런타임 생성 TMP가 렌더링되지 않는 문제를 방지했다.
  • M은 연보라 main + 시안 depth로 보석 느낌을 주고, S+는 청록, S는 골드 계열로 구분한다.

비주얼 / 세이버 / 파티클

파란색 가시성

  • Assets/VRBeatsKit/Settings/Settings.asset
  • Assets/VRBeatsKit/Scripts/Core/SaberTrailEffect.cs
  • Assets/VRBeatsKit/Scripts/Core/SliceTrailEffect.cs
  • Assets/VRBeatsKit/Scripts/Other/Spark.cs

파란색 세이버/트레일/스파크가 너무 연해서 잘 보이지 않던 문제를 줄였다.

결과 팝업 / 사버 표시

  • 게임오버/결과 시 세이버 표시 상태를 정리해 결과 화면이 더 읽기 쉽도록 했다.

주의 사항

  • 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. Game 씬 Play 후 HUD 좌우 위치 확인
  2. 시간바가 실제 노래 시간에 따라 차오르는지 확인
  3. 노래가 중간에 조기 종료되지 않는지 확인
  4. 낮은 큐브가 베기 편해졌는지 VR에서 확인
  5. 결과 화면에서 M/S+/S/F 등급 배지의 크기, 위치, 색상 확인
  6. M 달성 조건이 의도대로 최종 100만점일 때만 뜨는지 확인