2026-06-18 리듬게임 자동스틱
This commit is contained in:
Binary file not shown.
@@ -23,10 +23,14 @@ public class RhythmManager : MonoBehaviour
|
||||
[SerializeField] private bool _autoPlay; // 켜지면 모든 노트를 판정선 도달 순간 자동 Perfect 처리
|
||||
[SerializeField] private RhythmStick[] _autoPlaySticks; // 인덱스 = Note.Lane. 오토플레이 시 자동으로 휘두를 "자동 전용" 스틱들 (그랩 X)
|
||||
|
||||
[Header("오토플레이 전환 (수동 ↔ 자동 스틱)")]
|
||||
[SerializeField] private GameObject[] _autoPlayShowObjects; // 자동 시 켤 것: 자동 전용 스틱(손 모델 포함)
|
||||
[SerializeField] private GameObject[] _autoPlayHideObjects; // 자동 시 끌 것: 그랩 스틱·실제 손 등
|
||||
[SerializeField] private Collider[] _drumPadColliders; // 자동 시 비활성화할 드럼패드 콜라이더 (자동 타격이 수동 입력 안 끼치게)
|
||||
[Header("오토플레이 전환")]
|
||||
[Tooltip("자동 '체크'만 해도 즉시 숨길 수동(그랩) 스틱")]
|
||||
[SerializeField] private GameObject[] _manualSticks;
|
||||
[Tooltip("게임 시작 + 자동일 때만 숨길 실제 손 (체크만 했을 땐 유지 → 시작 버튼 등 조작 가능)")]
|
||||
[SerializeField] private GameObject[] _realHands;
|
||||
[Tooltip("게임 시작 + 자동일 때만 비활성화할 드럼패드 콜라이더")]
|
||||
[SerializeField] private Collider[] _drumPadColliders;
|
||||
// 자동 전용 스틱(손 포함)의 표시/숨김은 위 _autoPlaySticks의 GameObject를 그대로 토글한다.
|
||||
|
||||
[SerializeField] private GameObject StartButtonObj;
|
||||
|
||||
@@ -42,6 +46,8 @@ public class RhythmManager : MonoBehaviour
|
||||
private int _nextNoteIndex; // 다음에 소환할 노트 인덱스
|
||||
private bool _isPlaying; //곡이 재생 중인지 (종료 감지용)
|
||||
private bool _isCountingDown; // 시작 카운트다운 진행 중 여부 (중복 클릭 방지용)
|
||||
private bool _armedApplied; // 반영된 armed 상태 (자동 체크 → 수동 스틱 숨김)
|
||||
private bool _activeApplied; // 반영된 active 상태 (자동+진행 중 → 자동 스틱/손/드럼패드)
|
||||
private double _dspSongStart; // 오디오가 실제 시작되는 dsp 시각 (= SongTime 0 지점)
|
||||
private float _clipLength; // 곡 길이 캐시 (종료 감지용)
|
||||
private Func<float> _songTimeProvider; // 노트에 넘길 시간 제공자 (매 스폰마다 람다 재생성 방지용 캐시)
|
||||
@@ -75,11 +81,16 @@ private void Start()
|
||||
|
||||
_rhythmCats = FindObjectsByType<RhythmCat>(FindObjectsSortMode.None);
|
||||
|
||||
ApplyAutoPlayState(false); // 기준 상태: 자동 스틱 숨김, 수동 스틱/손·드럼패드 활성
|
||||
// 첫 Sync가 현재 상태를 반드시 한 번 반영하도록 반대값으로 초기화
|
||||
_armedApplied = !_autoPlay;
|
||||
_activeApplied = !AutoPlayActive;
|
||||
SyncAutoPlayState();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
SyncAutoPlayState(); // _autoPlay 변화를 매 프레임 감지(변화 없으면 즉시 반환) — 인스펙터 토글도 반영
|
||||
|
||||
if (!_isPlaying) return;
|
||||
|
||||
//곡이 끝나면(리드인 지나 곡 길이 도달) 정지·주변음 복구
|
||||
@@ -169,24 +180,66 @@ public void ChangeSong()
|
||||
public void EnableAutoPlay()
|
||||
{
|
||||
_autoPlay = true;
|
||||
ApplyAutoPlayState(true); // 자동 스틱 켜고, 수동 스틱·손·드럼패드 콜라이더 끔
|
||||
SyncAutoPlayState(); // 자동 스틱 켜고, 수동 스틱·손·드럼패드 콜라이더 끔
|
||||
}
|
||||
|
||||
// 오토플레이 비주얼/충돌 전환.
|
||||
// on=true → 자동 전용 스틱 표시 + 수동 스틱/손 숨김 + 드럼패드 콜라이더 비활성
|
||||
private void ApplyAutoPlayState(bool on)
|
||||
// UI Toggle 등에서 직접 연결용. 토글의 On Value Changed(bool)가 넘기는 값으로 켜고/끈다.
|
||||
public void SetAutoPlay(bool on)
|
||||
{
|
||||
if (_autoPlayShowObjects != null)
|
||||
foreach (GameObject go in _autoPlayShowObjects)
|
||||
if (go != null) go.SetActive(on);
|
||||
if (on) EnableAutoPlay();
|
||||
else DisableAutoPlay();
|
||||
}
|
||||
|
||||
if (_autoPlayHideObjects != null)
|
||||
foreach (GameObject go in _autoPlayHideObjects)
|
||||
if (go != null) go.SetActive(!on);
|
||||
// 오토플레이 수동 해제 (곡 도중에 꺼야 할 때). 곡 종료 시엔 StopSong이 알아서 끈다.
|
||||
public void DisableAutoPlay()
|
||||
{
|
||||
_autoPlay = false;
|
||||
|
||||
if (_drumPadColliders != null)
|
||||
foreach (Collider col in _drumPadColliders)
|
||||
if (col != null) col.enabled = !on;
|
||||
if (_autoPlaySticks != null) // 들려있던 자동 스틱 대기 자세로 복귀
|
||||
foreach (RhythmStick stick in _autoPlaySticks)
|
||||
if (stick != null) stick.ResetPose();
|
||||
|
||||
SyncAutoPlayState(); // 수동 스틱·손·드럼패드 콜라이더 복구
|
||||
}
|
||||
|
||||
// 오토플레이 상태를 두 단계로 나눠 비주얼에 반영 (변화 있을 때만):
|
||||
// - armed = 자동 '체크'만 해도 ON → 수동 스틱 숨김 (손/자동스틱은 그대로)
|
||||
// - active = 자동 + 곡 진행 중 → 자동 스틱 표시 + 실제 손 숨김 + 드럼패드 콜라이더 OFF
|
||||
// 자동 스틱/손 전환 기준: 자동이면서 카운트다운 시작~곡 종료 사이
|
||||
private bool AutoPlayActive => _autoPlay && (_isCountingDown || _isPlaying);
|
||||
|
||||
private void SyncAutoPlayState()
|
||||
{
|
||||
bool armed = _autoPlay;
|
||||
bool active = AutoPlayActive;
|
||||
|
||||
if (armed != _armedApplied)
|
||||
{
|
||||
_armedApplied = armed;
|
||||
SetActiveAll(_manualSticks, !armed); // 자동 체크 시 수동 스틱만 숨김
|
||||
}
|
||||
|
||||
if (active != _activeApplied)
|
||||
{
|
||||
_activeApplied = active;
|
||||
|
||||
if (_autoPlaySticks != null) // 자동 전용 스틱(손 포함) 표시/숨김
|
||||
foreach (RhythmStick s in _autoPlaySticks)
|
||||
if (s != null) s.gameObject.SetActive(active);
|
||||
|
||||
SetActiveAll(_realHands, !active); // 진행 중일 때만 실제 손 숨김
|
||||
|
||||
if (_drumPadColliders != null)
|
||||
foreach (Collider col in _drumPadColliders)
|
||||
if (col != null) col.enabled = !active;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetActiveAll(GameObject[] objs, bool on)
|
||||
{
|
||||
if (objs == null) return;
|
||||
foreach (GameObject go in objs)
|
||||
if (go != null) go.SetActive(on);
|
||||
}
|
||||
|
||||
// 시작 버튼 핸들러: 곧장 시작하지 않고 VR 준비 시간(카운트다운) 후 BeginSong 호출
|
||||
@@ -203,6 +256,7 @@ public void StartSong()
|
||||
private async Awaitable CountdownThenBeginAsync()
|
||||
{
|
||||
_isCountingDown = true;
|
||||
SyncAutoPlayState(); // 자동이면 카운트다운 시작 순간 자동 스틱 표시 + 실제 손 숨김
|
||||
try
|
||||
{
|
||||
OnCountdownStarted?.Invoke(); // CountdownHud 표시
|
||||
@@ -255,6 +309,7 @@ private void BeginSong()
|
||||
_audioSource.PlayScheduled(_dspSongStart);
|
||||
|
||||
_isPlaying = true;
|
||||
SyncAutoPlayState(); // 자동이면 이 순간 자동 스틱 표시 + 실제 손 숨김
|
||||
|
||||
//BGM·환경음을 낮춰 리듬게임 소리만 들리게
|
||||
if (SoundManager.Instance != null) SoundManager.Instance.EnterMinigameMode();
|
||||
@@ -273,16 +328,12 @@ public void StopSong()
|
||||
_audioSource.Stop();
|
||||
_isPlaying = false;
|
||||
|
||||
if (_autoPlay)
|
||||
{
|
||||
if (_autoPlaySticks != null) // 곡 끝나면 들려있던 스틱 대기 자세로 복귀
|
||||
foreach (RhythmStick stick in _autoPlaySticks)
|
||||
if (stick != null) stick.ResetPose();
|
||||
|
||||
ApplyAutoPlayState(false); // 수동 스틱·손·드럼패드 콜라이더 복구
|
||||
}
|
||||
if (_autoPlay && _autoPlaySticks != null) // 곡 끝나면 들려있던 스틱 대기 자세로 복귀
|
||||
foreach (RhythmStick stick in _autoPlaySticks)
|
||||
if (stick != null) stick.ResetPose();
|
||||
|
||||
_autoPlay = false; // 아이템 효과는 한 곡만 — 곡이 끝나면 자동 해제
|
||||
SyncAutoPlayState(); // 수동 스틱·손·드럼패드 콜라이더 복구
|
||||
|
||||
if (SoundManager.Instance != null) SoundManager.Instance.ExitMinigameMode();
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user