using UnityEngine; using System.Collections.Generic; using System.IO; public class MusicSpawner : MonoBehaviour { public AudioSource audioSource; public GameObject[] cube; // 0: 빨간색 박스, 1: 파란색 박스 public Transform[] point; // 4개의 스폰 지점 [Header("노래 설정")] [Tooltip("확장자와 Map_을 제외한 불러올 노래 제목을 적으세요 (예: Life, Virus)")] public string songName = "Life"; [Header("타이밍 설정")] public float noteSpeed = 2.0f; // Cube.cs의 속도 public float distanceToHit = 10.0f; // 스폰 지점부터 플레이어까지 거리 private List spawnNotes = new List(); private int nextSpawnIndex = 0; private float travelTime; void Start() { // 1. 도달 시간 계산 (거리 / 속도) travelTime = distanceToHit / noteSpeed; // 2. [수정] 입력한 songName을 바탕으로 동적 JSON 로드 string fileName = "Map_" + songName + ".json"; string filePath = Path.Combine(Application.streamingAssetsPath, fileName); if (File.Exists(filePath)) { string jsonString = File.ReadAllText(filePath); // 데이터 구조체 역직렬화 (MapData 공용 클래스 활용) MapData data = JsonUtility.FromJson(jsonString); spawnNotes = data.target; // 시간순 정렬로 스폰 꼬임 방지 spawnNotes.Sort((a, b) => a.time.CompareTo(b.time)); Debug.Log($"{fileName} 파일 정상 가동! 노드 데이터 확보 완료."); } else { Debug.LogError($"맵 파일을 찾을 수 없습니다! 지정 경로 확인 요망: {filePath}"); } if (audioSource != null && audioSource.clip != null) audioSource.Play(); } void Update() { if (audioSource == null || !audioSource.isPlaying) return; // 핵심: 현재 시간 + 날아가는 시간 >= 기록 시간일 때 스폰 if (nextSpawnIndex < spawnNotes.Count) { float currentTime = audioSource.time; var currentNote = spawnNotes[nextSpawnIndex]; if (currentTime + travelTime >= currentNote.time) { SpawnCube(currentNote.position, currentNote.colorType); nextSpawnIndex++; } } } void SpawnCube(int pos, int color) { // 유효성 검사 (인덱스 범위 확인) if (pos >= 0 && pos < point.Length && color >= 0 && color < cube.Length) { GameObject obj = Instantiate(cube[color], point[pos].position, point[pos].rotation); // 비트세이버 스타일 랜덤 회전 추가 obj.transform.Rotate(transform.forward, 90 * Random.Range(0, 4)); } } }