Unity
음반을 꽂으면 시작되는 4레인 리듬
전*원··수정됨 2026.07.21

RFID 가 심긴 LP 판을 슬롯에 꽂는 순간 판 위의 곡이 4레인 드럼 리듬 게임으로 바뀌어 내려오고, 가사는 음절 단위로 색이 바뀌며 박자와 함께 움직입니다. 이번 포스팅에서는 '즐거운 마음, 신나는 리듬' 콘텐츠의 기술적인 구현 과정을 공유합니다.

1. 시스템 아키텍처 개요
본 프로젝트는 크게 세 가지 단계로 구성됩니다.
- 곡 선택: RFID 리더가 LP 판에 심긴 UID 를 읽어 6곡 중 하나로 매핑하고, 물리 슬롯 삽입 센서로 게임 진입을 확정합니다.
- 리듬 게임: 선택된 곡의 가사 타이밍에서 동적 노트를 생성해 4레인 드럼 패드로 판정합니다.
- 가사 동기화: 음절별 상대 타이밍 테이블을 읽어, 현재 시간에 도달한 글자부터 색을 교체해 노래방처럼 가사가 흐르게 합니다.
메인 플랫폼은 Unity 단일 씬이며, LP 슬롯·드럼 패드·RFID 리더는 시리얼과 TCP 두 채널로 동시에 붙어 있습니다.
2. 주요 기술적 구현
2.1 RFID 인식과 LP 슬롯 감지 RFIDManager.cs, SerialManager_EnjoyMusic.cs)
RFIDManager.cs 는 EnjoyMusic_RFID.txt 파일에서 곡인덱스,UID 매핑을 미리 로드해 두고, 런타임에는 두 가지 경로로 RFID 를 받습니다. 키보드 에뮬레이션 리더는 Input.GetKeyDown(Return) 까지의 문자열을 UID 로 파싱하고, 네트워크형 리더는 SerialManager_EnjoyMusic.cs 의 TCP 리스너로 들어오는 {"uid": "...", "data": "..."} JSON 메시지를 SetRFIDFromNetwork(uid) 로 전달합니다.
RFID 는 먼저 인식되었지만 LP 판이 아직 슬롯에 꽂히지 않은 상황은, pendingUid 에 한 건만 임시 저장해 두고 이후 InsertLP 신호가 도착할 때 TryConsumePendingRFID() 가 처리하도록 했습니다. 슬롯 센서는 시리얼 [0xFA][Command][Lane] 3바이트 프로토콜을 통해 0x30 삽입, 0x31 추출, 0x31~0x34 4레인 드럼 입력을 같은 채널로 전송합니다.
2.2 리듬 게임 엔진과 판정 ChartTester.cs)
1,200줄 규모의 ChartTester.cs 가 Meta / Note / Chart 자료구조로 BPM·offset·keys·difficulty 를 관리하며 게임 전체를 주도합니다. 사전 제작된 JSON 차트를 로드할 수도 있지만, 기본 동작은 LoadChartFromLyrics() 로 가사 CSV 의 음절 타이밍에서 실시간 노트를 생성하는 방식이라, 가사만 있으면 별도 채보 제작 없이도 곡을 추가할 수 있습니다.
판정 로직 TryHitByPosition(lane, songTime) 은 드럼 입력 시점과 노트의 화면 위치·시간 차를 동시에 비교합니다.
- 판정선 범위: hitWindowPx = 80f
- 이른 판정 허용: hitEarlyWindowSec = 0.10f
- 늦은 판정 허용: hitLateWindowSec = 0.15f
- HIT 점수: scorePerHit = 1000 + 콤보 누적
노트는 scrollTimeSec = 2.5f 에 걸쳐 우측에서 좌측으로 흐르고, 곡 시작 전 5초 카운트다운과 globalNoteDelaySec = 5.0f 의 선행 지연을 둬 가사와 노트의 체감 동기를 맞췄습니다.
2.3 가사 음절 단위 동기화 InGameManager.cs)
InGameManager.cs 는 곡마다 가사 데이터를 받아 매 프레임 TMPro 리치텍스트로 재조립합니다. 각 음절에 구절 시작 시간 + 상대 타이밍이 붙어 있어, BuildColoredLyric() 이 현재 DSP 시간보다 앞선 음절은 coloredHex 컬러로, 뒤 음절은 원색으로 구분해 노래방처럼 색이 흘러가는 가사를 구현했습니다.
원본 CSV 는 절대·상대 시간을 혼용하는 경우가 있어 NormalizeAllPartsToRelativeTimes() 가 경계값을 자동 감지해 한 포맷으로 정규화하고, CloneLyrics() 로 원본을 딥카피해 재생 중 구조 변형이 원본 데이터로 역류하지 않도록 분리했습니다. 곡 전환 시 매번 깨끗한 데이터에서 다시 시작할 수 있는 안정성은 여기서 확보됩니다.
3. 사용자 경험(UX) 최적화
LP 을 꽂는 행위가 곧 시작 : 버튼 대신 물리 LP 판을 슬롯에 꽂는 아날로그 동작으로 곡을 선택하게 해, 어린 관람객에게도 "판을 올려 음악을 튼다"는 직관을 곧바로 이해하게 했습니다.
가사가 먼저 반응한다 : 노트보다 가사 색상이 실시간으로 흐르도록 설계해, 드럼을 처음 접하는 관람객도 가사를 따라가며 자연스럽게 박자를 익힐 수 있게 했습니다.
다른 판 삽입의 부드러운 전환 : 진행 중 다른 LP 가 꽂히면 5초 카운트다운 팝업으로 곡 전환 여부를 묻도록 해, 어린이의 손바뀜에도 화면이 튀지 않게 했습니다.
곡마다 달라지는 패턴 : 가사 타이밍에서 노트를 매번 랜덤 레인으로 생성해, 같은 곡을 연속 플레이해도 새로운 패턴으로 도전할 수 있도록 했습니다.
4. 마치며
기술적으로 이 프로젝트는 RFID·시리얼·TCP 세 가지 입력 채널을 하나의 매니저로 병합하고, 사전 제작된 JSON 차트가 없어도 가사 데이터만으로 리듬 게임을 구동할 수 있게 설계한 사례입니다. 덕분에 신곡 추가 시 가사 CSV 한 장만 준비하면 되며, 저작권 협의 속도에 맞춰 콘텐츠 라인업을 유연하게 교체할 수 있는 운영 구조를 확보했습니다.
향후에는 현재 단일 HIT 판정(1000점) 체계를 PERFECT·GREAT·MISS 3단계 판정과 타이밍 편차 기반 가중치로 세분화하여 '즐거움 점수 퍼센트' 게이지로 정식 환산할 계획입니다. 또한 LoadChartFromLyrics 의 레인 배치를 현재의 랜덤 방식에서 음절 세기·모음 패턴 기반으로 전환해, 같은 곡이라도 가사 내용에 어울리는 고정 채보가 생성될 수 있도록 확장할 예정입니다.
읽기 도구
약 6분 읽기
이 글이 도움이 되었나요?