using System; using UnityEngine; public class RhythmNoteSpawner : MonoBehaviour { // 레인(손)별 설정 - 전용 프리팹 + 가로 위치 오프셋 [Serializable] public class LaneVisual { public RhythmNoteInstance Prefab; // 이 레인 전용 노트 프리팹 (왼손/오른손 다른 모양) public Vector3 Offset; // 스폰/판정 위치 가로 오프셋 (왼손 -x, 오른손 +x 등) } [SerializeField] private RhythmNoteInstance _notePrefab; // 기본 프리팹 (레인 전용 미지정 시 사용) [SerializeField] private Transform _spawnPoint; // 노트가 생겨나는 위치(미지정 시 자기 위치) [SerializeField] private Transform _judgmentLine; // 목적지(판정선) [SerializeField] private LaneVisual[] _lanes; // 인덱스 = Note.Lane (RhythmChart.LanePitches 순서와 일치) // 노트 생성, 목적지·타이밍 주입. 레인에 따라 프리팹/위치만 다르게(판정은 동일) public RhythmNoteInstance SpawnNote(Note note, float spawnTime, Func songTime, Action onMiss = null) { Transform origin = _spawnPoint != null ? _spawnPoint : transform; // 레인 범위 밖이면 기본 프리팹/오프셋 0 LaneVisual lane = (_lanes != null && note.Lane >= 0 && note.Lane < _lanes.Length) ? _lanes[note.Lane] : null; RhythmNoteInstance prefab = (lane != null && lane.Prefab != null) ? lane.Prefab : _notePrefab; // 오프셋을 origin 방향 기준으로 적용해 레인을 평행 이동(start·target 동일 오프셋이라 경로가 곧음) Vector3 worldOffset = lane != null ? origin.rotation * lane.Offset : Vector3.zero; Vector3 start = origin.position + worldOffset; Vector3 target = _judgmentLine.position + worldOffset; RhythmNoteInstance instance = Instantiate(prefab, start, origin.rotation, transform); instance.Setup(start, target, spawnTime, note.Time, note.Lane, songTime, onMiss); return instance; } }