2026-06-15 리듬게임 자동기능
This commit is contained in:
@@ -19,6 +19,10 @@ public class RhythmManager : MonoBehaviour
|
||||
[Header("효과음")]
|
||||
[SerializeField] private AudioClip _hitSfx; // 내려칠 때마다 재생 (판정과 무관, 헛침 포함)
|
||||
|
||||
[Header("오토플레이 (아이템)")]
|
||||
[SerializeField] private bool _autoPlay; // 켜지면 모든 노트를 판정선 도달 순간 자동 Perfect 처리
|
||||
[SerializeField] private RhythmStick[] _autoPlaySticks; // 인덱스 = Note.Lane. 오토플레이 시 자동으로 휘두를 스틱들
|
||||
|
||||
[SerializeField] private GameObject StartButtonObj;
|
||||
|
||||
// 모든 타이밍의 기준. 오디오 클럭(dspTime) 기반이라 리드인 동안 음수(-leadTime→0)로 흐른다
|
||||
@@ -40,6 +44,8 @@ public class RhythmManager : MonoBehaviour
|
||||
public event Action<RhythmScore> OnScoreChanged; // 점수/콤보가 바뀔 때 (실시간 HUD)
|
||||
public event Action<RhythmScore> OnSongFinished; // 곡이 끝났을 때 (결과창)
|
||||
|
||||
private RhythmCat[] _rhythmCats;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_songTimeProvider = () => SongTime; // 한 번만 만들어 모든 노트가 공유
|
||||
@@ -51,6 +57,8 @@ private void Start()
|
||||
|
||||
InputManager.Instance.OnKey_Left_Event += OnPlayerInput;
|
||||
InputManager.Instance.OnKey_Right_Event += OnPlayerInput;
|
||||
|
||||
_rhythmCats = FindObjectsByType<RhythmCat>(FindObjectsSortMode.None);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
@@ -65,6 +73,59 @@ private void Update()
|
||||
}
|
||||
|
||||
SpawnDueNotes();
|
||||
|
||||
if (_autoPlay)
|
||||
{
|
||||
DriveAutoPlaySticks(); // 다가오는 노트에 맞춰 스틱을 들었다 내림 (판정 전에 호출)
|
||||
AutoHitDueNotes(); // 판정선 도달한 노트 자동 Perfect
|
||||
}
|
||||
}
|
||||
|
||||
// 오토플레이: 레인별로 가장 임박한 노트에 맞춰 스틱을 휘두름
|
||||
private void DriveAutoPlaySticks()
|
||||
{
|
||||
if (_autoPlaySticks == null) return;
|
||||
|
||||
for (int lane = 0; lane < _autoPlaySticks.Length; lane++)
|
||||
{
|
||||
RhythmStick stick = _autoPlaySticks[lane];
|
||||
if (stick == null) continue;
|
||||
|
||||
// 이 레인에서 아직 안 친(미래의) 노트 중 가장 가까운 타격 시각
|
||||
float nextHit = float.PositiveInfinity;
|
||||
foreach (RhythmNoteInstance note in _activeNotes)
|
||||
{
|
||||
int noteLane = Mathf.Clamp(note.Lane, 0, _autoPlaySticks.Length - 1);
|
||||
if (noteLane != lane) continue;
|
||||
if (note.HitTime < SongTime) continue; // 이미 지난(곧 처리될) 노트 제외
|
||||
if (note.HitTime < nextHit) nextHit = note.HitTime;
|
||||
}
|
||||
|
||||
stick.Drive(nextHit - SongTime); // 다가오는 노트 없으면 +∞ → 대기 자세
|
||||
}
|
||||
}
|
||||
|
||||
// 오토플레이: 판정선에 도달한(HitTime을 지난) 노트를 자동으로 Perfect 처리
|
||||
private void AutoHitDueNotes()
|
||||
{
|
||||
// 뒤에서부터 순회해야 처리한 노트를 안전하게 리스트에서 제거할 수 있다
|
||||
for (int i = _activeNotes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
RhythmNoteInstance note = _activeNotes[i];
|
||||
if (SongTime < note.HitTime) continue; // 아직 판정선 도달 전이면 건너뜀
|
||||
|
||||
// 수동 입력과 동일한 연출: 내려치는 효과음 + 히트 이펙트
|
||||
if (_hitSfx != null && SoundManager.Instance != null)
|
||||
SoundManager.Instance.PlaySFX(_hitSfx);
|
||||
|
||||
if (note.TryGetComponent(out RhythmProjectile projectile))
|
||||
projectile.Detonate();
|
||||
|
||||
_activeNotes.RemoveAt(i);
|
||||
Destroy(note.gameObject);
|
||||
|
||||
ApplyJudge(Result.Perfect); // 시간차 ≈ 0 → 항상 Perfect
|
||||
}
|
||||
}
|
||||
|
||||
// SongTime 기준으로 소환할 때가 된 노트들을 순서대로 생성
|
||||
@@ -87,6 +148,9 @@ public void ChangeSong()
|
||||
_audioSource.clip = _currentChart.SongClip;
|
||||
}
|
||||
|
||||
// 오토플레이 아이템 사용: 곡 시작 전(또는 도중)에 호출하면 남은 노트가 전부 자동 Perfect
|
||||
public void EnableAutoPlay() => _autoPlay = true;
|
||||
|
||||
// 곡 재생 + 채보 로드
|
||||
public void StartSong()
|
||||
{
|
||||
@@ -110,6 +174,11 @@ public void StartSong()
|
||||
|
||||
//BGM·환경음을 낮춰 리듬게임 소리만 들리게
|
||||
if (SoundManager.Instance != null) SoundManager.Instance.EnterMinigameMode();
|
||||
|
||||
for(int i=0;i<_rhythmCats.Length;i++)
|
||||
{
|
||||
_rhythmCats[i].Dance(i*1f);
|
||||
}
|
||||
}
|
||||
|
||||
// 곡 정지 + 주변음 복구
|
||||
@@ -120,9 +189,20 @@ public void StopSong()
|
||||
_audioSource.Stop();
|
||||
_isPlaying = false;
|
||||
|
||||
if (_autoPlay && _autoPlaySticks != null) // 곡 끝나면 들려있던 스틱 대기 자세로 복귀
|
||||
foreach (RhythmStick stick in _autoPlaySticks)
|
||||
if (stick != null) stick.ResetPose();
|
||||
|
||||
_autoPlay = false; // 아이템 효과는 한 곡만 — 곡이 끝나면 자동 해제
|
||||
|
||||
if (SoundManager.Instance != null) SoundManager.Instance.ExitMinigameMode();
|
||||
|
||||
OnSongFinished?.Invoke(Score); // 결과창 표시
|
||||
|
||||
for(int i=0;i<_rhythmCats.Length;i++)
|
||||
{
|
||||
_rhythmCats[i].DanceStop();
|
||||
}
|
||||
}
|
||||
|
||||
// 노트가 판정선을 지나쳐 스스로 Miss 처리될 때 호출 (노트는 이미 자기 파괴됨)
|
||||
|
||||
Reference in New Issue
Block a user