Revert "Merge pull request '리듬게임' (#5) from CatsRhythmGame into main"
This reverts commit58385bf819, reversing changes made to8369e2ab51.
This commit is contained in:
@@ -1,50 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public enum Result { Perfect, Good, Bad, Miss }
|
||||
public enum Result { Perfect, Good, Miss }
|
||||
public class RhythmManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private AudioSource _audioSource;
|
||||
[SerializeField] private RhythmChart _currentChart;
|
||||
[SerializeField] private RhythmNoteSpawner _spawner;
|
||||
[SerializeField] private float _leadTime = 1f; // 노트가 생성돼 판정선까지 흐르는 시간(초)
|
||||
|
||||
[Header("판정 윈도우 (초, 절대 시간차 기준)")]
|
||||
[SerializeField] private float _perfectWindow = 0.05f;
|
||||
[SerializeField] private float _goodWindow = 0.10f;
|
||||
[SerializeField] private float _badWindow = 0.15f; // 이 밖이면 입력 무시(헛침)
|
||||
|
||||
[Header("효과음")]
|
||||
[SerializeField] private AudioClip _hitSfx; // 내려칠 때마다 재생 (판정과 무관, 헛침 포함)
|
||||
|
||||
[Header("오토플레이 (아이템)")]
|
||||
[SerializeField] private bool _autoPlay; // 켜지면 모든 노트를 판정선 도달 순간 자동 Perfect 처리
|
||||
[SerializeField] private RhythmStick[] _autoPlaySticks; // 인덱스 = Note.Lane. 오토플레이 시 자동으로 휘두를 스틱들
|
||||
|
||||
[SerializeField] private GameObject StartButtonObj;
|
||||
|
||||
// 모든 타이밍의 기준. 오디오 클럭(dspTime) 기반이라 리드인 동안 음수(-leadTime→0)로 흐른다
|
||||
public float SongTime => (float)(AudioSettings.dspTime - _dspSongStart);
|
||||
[SerializeField] private float _leadTime = 2f; // 노트가 생성돼 판정선까지 흐르는 시간(초)
|
||||
public float SongTime => _audioSource.time; // 모든 타이밍의 기준
|
||||
|
||||
private List<Note> SongNoteList;
|
||||
private int _nextNoteIndex; // 다음에 소환할 노트 인덱스
|
||||
private bool _isPlaying; //곡이 재생 중인지 (종료 감지용)
|
||||
private double _dspSongStart; // 오디오가 실제 시작되는 dsp 시각 (= SongTime 0 지점)
|
||||
private float _clipLength; // 곡 길이 캐시 (종료 감지용)
|
||||
private Func<float> _songTimeProvider; // 노트에 넘길 시간 제공자 (매 스폰마다 람다 재생성 방지용 캐시)
|
||||
private readonly List<RhythmNoteInstance> _activeNotes = new(); // 화면에 떠 있는(아직 처리 안 된) 노트들
|
||||
|
||||
// 점수 상태 (HUD가 읽음). 누적 로직은 RhythmScore가 전담
|
||||
public RhythmScore Score { get; } = new();
|
||||
|
||||
public event Action OnSongStarted; // 곡 시작 (ScoreHud 표시 / ResultHud 숨김)
|
||||
public event Action<Result> OnJudged; // 노트 하나가 판정될 때마다 (HUD 연출용)
|
||||
public event Action<RhythmScore> OnScoreChanged; // 점수/콤보가 바뀔 때 (실시간 HUD)
|
||||
public event Action<RhythmScore> OnSongFinished; // 곡이 끝났을 때 (결과창)
|
||||
|
||||
private RhythmCat[] _rhythmCats;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -54,78 +24,18 @@ private void Awake()
|
||||
private void Start()
|
||||
{
|
||||
ChangeSong();
|
||||
|
||||
InputManager.Instance.OnKey_Left_Event += OnPlayerInput;
|
||||
InputManager.Instance.OnKey_Right_Event += OnPlayerInput;
|
||||
|
||||
_rhythmCats = FindObjectsByType<RhythmCat>(FindObjectsSortMode.None);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isPlaying) return;
|
||||
|
||||
//곡이 끝나면(리드인 지나 곡 길이 도달) 정지·주변음 복구
|
||||
if (SongTime >= _clipLength)
|
||||
//재생 중이던 곡이 끝나면 주변음 복구
|
||||
if (_isPlaying && !_audioSource.isPlaying)
|
||||
{
|
||||
StopSong();
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if (_isPlaying) SpawnDueNotes();
|
||||
}
|
||||
|
||||
// SongTime 기준으로 소환할 때가 된 노트들을 순서대로 생성
|
||||
@@ -137,8 +47,7 @@ private void SpawnDueNotes()
|
||||
{
|
||||
Note note = SongNoteList[_nextNoteIndex];
|
||||
// spawnTime은 실제 프레임 시각이 아니라 이론값(note.Time - _leadTime)으로 줘야 보간이 정확
|
||||
RhythmNoteInstance instance = _spawner.SpawnNote(note, note.Time - _leadTime, _songTimeProvider, OnNoteMissed);
|
||||
_activeNotes.Add(instance);
|
||||
_spawner.SpawnNote(note, note.Time - _leadTime, _songTimeProvider, OnNoteMissed);
|
||||
_nextNoteIndex++;
|
||||
}
|
||||
}
|
||||
@@ -148,125 +57,41 @@ public void ChangeSong()
|
||||
_audioSource.clip = _currentChart.SongClip;
|
||||
}
|
||||
|
||||
// 오토플레이 아이템 사용: 곡 시작 전(또는 도중)에 호출하면 남은 노트가 전부 자동 Perfect
|
||||
public void EnableAutoPlay() => _autoPlay = true;
|
||||
|
||||
// 곡 재생 + 채보 로드
|
||||
public void StartSong()
|
||||
{
|
||||
SongNoteList = _currentChart.GenerateNotes();
|
||||
_nextNoteIndex = 0;
|
||||
_activeNotes.Clear();
|
||||
|
||||
Score.Reset();
|
||||
OnSongStarted?.Invoke(); // ScoreHud 표시 / ResultHud 숨김
|
||||
OnScoreChanged?.Invoke(Score); // HUD 초기화(0점)
|
||||
StartButtonObj.SetActive(false);
|
||||
|
||||
_clipLength = _audioSource.clip != null ? _audioSource.clip.length : 0f;
|
||||
|
||||
// 리드인: 지금부터 _leadTime 뒤에 오디오 시작.
|
||||
// 그 사이 SongTime이 -_leadTime→0으로 흘러 첫 노트(0초 부근)도 충분히 날아온다
|
||||
_dspSongStart = AudioSettings.dspTime + _leadTime;
|
||||
_audioSource.PlayScheduled(_dspSongStart);
|
||||
|
||||
_audioSource.Play();
|
||||
_isPlaying = true;
|
||||
|
||||
//BGM·환경음을 낮춰 리듬게임 소리만 들리게
|
||||
if (SoundManager.Instance != null) SoundManager.Instance.EnterMinigameMode();
|
||||
|
||||
for(int i=0;i<_rhythmCats.Length;i++)
|
||||
{
|
||||
_rhythmCats[i].Dance(i*1f);
|
||||
}
|
||||
}
|
||||
|
||||
// 곡 정지 + 주변음 복구
|
||||
public void StopSong()
|
||||
{
|
||||
if (!_isPlaying) return; // 중복 호출 방지(결과창 두 번 뜨는 것 차단)
|
||||
|
||||
_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 처리될 때 호출 (노트는 이미 자기 파괴됨)
|
||||
// 노트가 판정선을 지나쳐 스스로 Miss 처리될 때 호출
|
||||
private void OnNoteMissed(RhythmNoteInstance note)
|
||||
{
|
||||
_activeNotes.Remove(note);
|
||||
ApplyJudge(Result.Miss);
|
||||
Debug.Log("[Rhythm] Miss (지나침)");
|
||||
// TODO: 점수/콤보 시스템 연결 시 Miss 반영
|
||||
}
|
||||
|
||||
public void OnPlayerInput()
|
||||
{
|
||||
if (!_isPlaying) return;
|
||||
|
||||
// 판정과 무관하게 내려칠 때마다 효과음 (헛침 포함)
|
||||
if (_hitSfx != null && SoundManager.Instance != null)
|
||||
SoundManager.Instance.PlaySFX(_hitSfx);
|
||||
|
||||
if (_activeNotes.Count == 0) return;
|
||||
|
||||
// 판정선에 가장 가까운(시간차 최소) 노트 탐색
|
||||
RhythmNoteInstance target = null;
|
||||
float bestDiff = float.MaxValue;
|
||||
foreach (RhythmNoteInstance note in _activeNotes)
|
||||
{
|
||||
float diff = Mathf.Abs(SongTime - note.HitTime);
|
||||
if (diff < bestDiff)
|
||||
{
|
||||
bestDiff = diff;
|
||||
target = note;
|
||||
}
|
||||
}
|
||||
|
||||
Result result = Judge(bestDiff);
|
||||
if (result == Result.Miss) return; // 히트 범위 밖이면 입력 무시 (노트 소비 안 함)
|
||||
|
||||
// 성공 판정 → 히트 이펙트 + 노트 소비
|
||||
if (result == Result.Perfect || result == Result.Good)
|
||||
{
|
||||
// 이펙트는 노트에서 분리돼 따로 재생되므로 노트를 바로 파괴해도 됨
|
||||
if (target.TryGetComponent(out RhythmProjectile projectile))
|
||||
projectile.Detonate();
|
||||
}
|
||||
_activeNotes.Remove(target);
|
||||
Destroy(target.gameObject);
|
||||
|
||||
ApplyJudge(result);
|
||||
Debug.Log($"[Rhythm] {result} (diff {bestDiff:F3}s)");
|
||||
}
|
||||
|
||||
// 판정 결과를 점수에 반영하고 이벤트로 알림
|
||||
private void ApplyJudge(Result result)
|
||||
{
|
||||
Score.Apply(result);
|
||||
OnJudged?.Invoke(result);
|
||||
OnScoreChanged?.Invoke(Score);
|
||||
}
|
||||
|
||||
// diff = 절대 시간차(초). 윈도우 안이면 Perfect/Good/Bad, 밖이면 Miss(입력 무시)
|
||||
public Result Judge(float diff)
|
||||
{
|
||||
if (diff <= _perfectWindow) return Result.Perfect;
|
||||
if (diff <= _goodWindow) return Result.Good;
|
||||
if (diff <= _badWindow) return Result.Bad;
|
||||
return Result.Miss;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,6 @@ public class InputManager : MonoBehaviour, GameInput.IPlayerActions
|
||||
|
||||
// ─── 입력 이벤트들 (PlayerController 등이 구독) ──────────────────────
|
||||
public event Action OnJump_Event; // 한 번씩 (눌렀을 때)
|
||||
|
||||
//키보드로 테스트용
|
||||
public event Action OnKey_Left_Event;
|
||||
public event Action OnKey_Right_Event;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -43,16 +39,4 @@ public void OnJump(InputAction.CallbackContext ctx)
|
||||
if (ctx.phase == InputActionPhase.Started)
|
||||
OnJump_Event?.Invoke();
|
||||
}
|
||||
|
||||
public void OnKey_Left(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if (ctx.phase == InputActionPhase.Started)
|
||||
OnKey_Left_Event?.Invoke();
|
||||
}
|
||||
|
||||
public void OnKey_Right(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if (ctx.phase == InputActionPhase.Started)
|
||||
OnKey_Right_Event?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
public class RoomMoveButton : MonoBehaviour
|
||||
{
|
||||
[Header("이 버튼을 눌렀을 때 이동할 방 번호 입력")]
|
||||
[Header("이 버튼을 눌렀을 때 이동할 방 번호 입력")]
|
||||
[SerializeField] private int targetRoomNumber;
|
||||
|
||||
public void OnClickMoveRoom()
|
||||
{
|
||||
if (RoomRouteManager.Instance == null)
|
||||
{
|
||||
Debug.LogError("RoomRouteManager가 없습니다.");
|
||||
Debug.LogError("RoomRouteManager가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,50 +19,50 @@ private void Update()
|
||||
return;
|
||||
}
|
||||
|
||||
// C키: 방문 안 한 방 중 랜덤 후보 뽑기
|
||||
// C키: 방문 안 한 방 중 랜덤 후보 뽑기
|
||||
if (Keyboard.current.cKey.wasPressedThisFrame)
|
||||
{
|
||||
currentChoices = RoomRouteManager.Instance.GetRandomNextRooms();
|
||||
|
||||
Debug.Log($"현재 선택 가능한 후보 개수: {currentChoices.Count}");
|
||||
Debug.Log($"현재 선택 가능한 후보 개수: {currentChoices.Count}");
|
||||
|
||||
for (int i = 0; i < currentChoices.Count; i++)
|
||||
{
|
||||
Debug.Log($"{i + 1}번 선택지 → 방 번호: {currentChoices[i].roomNumber}, 씬 이름: {currentChoices[i].sceneName}");
|
||||
Debug.Log($"{i + 1}번 선택지 → 방 번호: {currentChoices[i].roomNumber}, 씬 이름: {currentChoices[i].sceneName}");
|
||||
}
|
||||
}
|
||||
|
||||
// 1키: 첫 번째 후보 선택
|
||||
// 1키: 첫 번째 후보 선택
|
||||
if (Keyboard.current.digit1Key.wasPressedThisFrame)
|
||||
{
|
||||
MoveToChoice(0);
|
||||
}
|
||||
|
||||
// 2키: 두 번째 후보 선택
|
||||
// 2키: 두 번째 후보 선택
|
||||
if (Keyboard.current.digit2Key.wasPressedThisFrame)
|
||||
{
|
||||
MoveToChoice(1);
|
||||
}
|
||||
|
||||
// T키: 방문 상태 확인
|
||||
// T키: 방문 상태 확인
|
||||
if (Keyboard.current.tKey.wasPressedThisFrame)
|
||||
{
|
||||
Debug.Log($"방문한 방 개수: {RoomRouteManager.Instance.VisitedRoomCount} / {RoomRouteManager.Instance.TotalRoomCount}");
|
||||
Debug.Log($"현재 방 번호: {RoomRouteManager.Instance.CurrentRoomNumber}");
|
||||
Debug.Log($"방문한 방 개수: {RoomRouteManager.Instance.VisitedRoomCount} / {RoomRouteManager.Instance.TotalRoomCount}");
|
||||
Debug.Log($"현재 방 번호: {RoomRouteManager.Instance.CurrentRoomNumber}");
|
||||
}
|
||||
|
||||
// X키: 테스트용 방문 기록 초기화
|
||||
// X키: 테스트용 방문 기록 초기화
|
||||
if (Keyboard.current.xKey.wasPressedThisFrame)
|
||||
{
|
||||
Debug.Log("방문 기록 초기화");
|
||||
Debug.Log("방문 기록 초기화");
|
||||
currentChoices.Clear();
|
||||
RoomRouteManager.Instance.ResetVisitedRooms();
|
||||
}
|
||||
|
||||
// F키: 모든 방 방문 후 마지막 씬 이동 테스트
|
||||
// F키: 모든 방 방문 후 마지막 씬 이동 테스트
|
||||
if (Keyboard.current.fKey.wasPressedThisFrame)
|
||||
{
|
||||
Debug.Log("마지막 씬 이동 테스트");
|
||||
Debug.Log("마지막 씬 이동 테스트");
|
||||
RoomRouteManager.Instance.MoveToFinalScene();
|
||||
}
|
||||
}
|
||||
@@ -71,19 +71,19 @@ private void MoveToChoice(int index)
|
||||
{
|
||||
if (currentChoices == null || currentChoices.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("먼저 C키를 눌러 랜덤 후보를 뽑아야 합니다.");
|
||||
Debug.LogWarning("먼저 C키를 눌러 랜덤 후보를 뽑아야 합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= currentChoices.Count)
|
||||
{
|
||||
Debug.LogWarning("해당 번호의 선택지가 없습니다.");
|
||||
Debug.LogWarning("해당 번호의 선택지가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
int targetRoomNumber = currentChoices[index].roomNumber;
|
||||
|
||||
Debug.Log($"{index + 1}번 선택지 선택 → 방 {targetRoomNumber} 이동");
|
||||
Debug.Log($"{index + 1}번 선택지 선택 → 방 {targetRoomNumber} 이동");
|
||||
|
||||
currentChoices.Clear();
|
||||
|
||||
|
||||
@@ -8,23 +8,23 @@ public class RoomRouteManager : MonoBehaviour
|
||||
[System.Serializable]
|
||||
public class RoomData
|
||||
{
|
||||
[Header("방 번호 입력")]
|
||||
[Header("방 번호 입력")]
|
||||
public int roomNumber;
|
||||
|
||||
[Header("이 방에 해당하는 Scene 이름 입력")]
|
||||
[Header("이 방에 해당하는 Scene 이름 입력")]
|
||||
public string sceneName;
|
||||
}
|
||||
|
||||
[Header("전체 방 정보 입력")]
|
||||
[Header("전체 방 정보 입력")]
|
||||
[SerializeField] private List<RoomData> rooms = new List<RoomData>();
|
||||
|
||||
[Header("시작 방 번호 입력")]
|
||||
[Header("시작 방 번호 입력")]
|
||||
[SerializeField] private int startRoomNumber;
|
||||
|
||||
[Header("랜덤 선택지 개수")]
|
||||
[Header("랜덤 선택지 개수")]
|
||||
[SerializeField] private int randomChoiceCount = 2;
|
||||
|
||||
[Header("모든 방 방문 후 이동할 마지막 Scene 이름")]
|
||||
[Header("모든 방 방문 후 이동할 마지막 Scene 이름")]
|
||||
[SerializeField] private string finalSceneName;
|
||||
|
||||
private int _currentRoomNumber;
|
||||
@@ -54,7 +54,7 @@ private void Awake()
|
||||
}
|
||||
}
|
||||
|
||||
// 방문하지 않은 방 전체 반환
|
||||
// 방문하지 않은 방 전체 반환
|
||||
public List<RoomData> GetUnvisitedRooms()
|
||||
{
|
||||
List<RoomData> result = new List<RoomData>();
|
||||
@@ -70,7 +70,7 @@ public List<RoomData> GetUnvisitedRooms()
|
||||
return result;
|
||||
}
|
||||
|
||||
// 대화 선택지에 보여줄 랜덤 방 목록 반환
|
||||
// 대화 선택지에 보여줄 랜덤 방 목록 반환
|
||||
public List<RoomData> GetRandomNextRooms()
|
||||
{
|
||||
List<RoomData> unvisitedRooms = GetUnvisitedRooms();
|
||||
@@ -89,18 +89,18 @@ public List<RoomData> GetRandomNextRooms()
|
||||
return randomRooms;
|
||||
}
|
||||
|
||||
// 버튼이나 대화 선택지에서 호출
|
||||
// 버튼이나 대화 선택지에서 호출
|
||||
public void MoveToRoom(int roomNumber)
|
||||
{
|
||||
if (SceneLoadManager.Instance == null)
|
||||
{
|
||||
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
||||
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SceneLoadManager.Instance.IsChangingScene)
|
||||
{
|
||||
Debug.Log("이미 씬 이동 중입니다.");
|
||||
Debug.Log("이미 씬 이동 중입니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,19 +108,19 @@ public void MoveToRoom(int roomNumber)
|
||||
|
||||
if (targetRoom == null)
|
||||
{
|
||||
Debug.LogWarning($"방 정보를 찾을 수 없습니다. 방 번호: {roomNumber}");
|
||||
Debug.LogWarning($"방 정보를 찾을 수 없습니다. 방 번호: {roomNumber}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_visitedRooms.Contains(roomNumber))
|
||||
{
|
||||
Debug.Log($"이미 방문한 방입니다. 방 번호: {roomNumber}");
|
||||
Debug.Log($"이미 방문한 방입니다. 방 번호: {roomNumber}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(targetRoom.sceneName))
|
||||
{
|
||||
Debug.LogWarning($"방 {roomNumber}의 Scene 이름이 비어있습니다.");
|
||||
Debug.LogWarning($"방 {roomNumber}의 Scene 이름이 비어있습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -130,14 +130,14 @@ public void MoveToRoom(int roomNumber)
|
||||
SceneLoadManager.Instance.RequestSceneChange(targetRoom.sceneName);
|
||||
}
|
||||
|
||||
// 랜덤 방 하나로 바로 이동하고 싶을 때 사용
|
||||
// 랜덤 방 하나로 바로 이동하고 싶을 때 사용
|
||||
public void MoveToRandomRoom()
|
||||
{
|
||||
List<RoomData> unvisitedRooms = GetUnvisitedRooms();
|
||||
|
||||
if (unvisitedRooms.Count <= 0)
|
||||
{
|
||||
Debug.Log("방문하지 않은 방이 없습니다.");
|
||||
Debug.Log("방문하지 않은 방이 없습니다.");
|
||||
|
||||
if (IsAllRoomsVisited())
|
||||
{
|
||||
@@ -162,25 +162,25 @@ public void MoveToFinalScene()
|
||||
{
|
||||
if (!IsAllRoomsVisited())
|
||||
{
|
||||
Debug.Log("아직 모든 방을 방문하지 않았습니다.");
|
||||
Debug.Log("아직 모든 방을 방문하지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SceneLoadManager.Instance == null)
|
||||
{
|
||||
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
||||
Debug.LogError("SceneLoadManager가 씬에 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SceneLoadManager.Instance.IsChangingScene)
|
||||
{
|
||||
Debug.Log("이미 씬 이동 중입니다.");
|
||||
Debug.Log("이미 씬 이동 중입니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(finalSceneName))
|
||||
{
|
||||
Debug.LogWarning("마지막 Scene 이름이 비어있습니다.");
|
||||
Debug.LogWarning("마지막 Scene 이름이 비어있습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user