using System.Collections; using UnityEngine; public class RaftStartManager : MonoBehaviour { private enum StartState { Ready, WaitingForKeyGrab, Starting, Riding, Arrived, Failed } [Header("References")] [SerializeField] private RaftRiverController raftController; [SerializeField] private SteeringKeyXR steeringKey; [Tooltip("현재는 캡슐 요정. 나중에 요정 캐릭터 모델로 교체할 부모 오브젝트를 넣으면 됩니다.")] [SerializeField] private GameObject fairyObject; [Header("Obstacles")] [Tooltip("뗏목 출발 시 함께 작동할 코뿔소들입니다.")] [SerializeField] private RhinoObstacle[] rhinos; [Header("Health")] [SerializeField] private RaftHealth raftHealth; [Header("Start Settings")] [SerializeField] private bool waitForKeyGrab = true; [Tooltip("키를 잡은 뒤 뗏목이 완전히 출발 속도에 도달하기까지 걸리는 시간")] [SerializeField] private float startAccelerationDuration = 2.0f; [Tooltip("출발 직후 바로 요정이 사라질지 여부")] [SerializeField] private bool hideFairyOnStart = true; [Header("Debug")] [SerializeField] private bool showDebugLog = true; private StartState state = StartState.Ready; private Coroutine startRoutine; private void Start() { SetupStartState(); } private void Update() { if (state != StartState.WaitingForKeyGrab) return; if (!waitForKeyGrab) return; if (steeringKey != null && steeringKey.IsGrabbed) { BeginRaftRide(); } } private void SetupStartState() { ResolveReferences(); state = StartState.WaitingForKeyGrab; if (raftController != null) { raftController.StopRaft(); raftController.SetSpeedMultiplier(0f); } if (raftHealth != null) { raftHealth.ResetHealth(); } StopAllRhinos(); if (fairyObject != null) { fairyObject.SetActive(true); } if (showDebugLog) { Debug.Log("[RaftStartManager] 시작 준비 완료. 키를 잡으면 뗏목이 출발합니다."); } } private void ResolveReferences() { if (raftController == null) raftController = FindFirstObjectByType(); if (steeringKey == null) steeringKey = FindFirstObjectByType(); if (raftHealth == null) raftHealth = FindFirstObjectByType(); if (rhinos == null || rhinos.Length == 0) rhinos = FindObjectsByType(FindObjectsSortMode.None); } public void BeginRaftRide() { if (state == StartState.Starting || state == StartState.Riding) return; state = StartState.Starting; if (hideFairyOnStart && fairyObject != null) { fairyObject.SetActive(false); } if (startRoutine != null) StopCoroutine(startRoutine); startRoutine = StartCoroutine(StartRaftSmoothly()); } private IEnumerator StartRaftSmoothly() { if (raftController == null) { Debug.LogWarning("[RaftStartManager] RaftRiverController가 연결되지 않았습니다.", this); yield break; } raftController.SetSpeedMultiplier(0f); raftController.ResumeRaft(); StartAllRhinos(); if (showDebugLog) { Debug.Log("[RaftStartManager] 뗏목 출발 시작. 코뿔소 장애물도 시작합니다."); } float timer = 0f; float duration = Mathf.Max(0.01f, startAccelerationDuration); while (timer < duration) { timer += Time.deltaTime; float t = Mathf.Clamp01(timer / duration); float smoothT = t * t * (3f - 2f * t); raftController.SetSpeedMultiplier(smoothT); yield return null; } raftController.SetSpeedMultiplier(1f); state = StartState.Riding; if (showDebugLog) { Debug.Log("[RaftStartManager] 뗏목 정상 운항 속도 도달."); } } public void OnRaftArrived() { if (state == StartState.Arrived) return; state = StartState.Arrived; if (raftController != null) { raftController.SetSpeedMultiplier(0f); } StopAllRhinos(); if (showDebugLog) { Debug.Log("[RaftStartManager] 목적지 도착. 뗏목 구간 종료. 코뿔소 장애물 정지."); } } public void OnRaftFailed() { if (state == StartState.Failed) return; state = StartState.Failed; if (raftController != null) { raftController.StopRaft(); raftController.SetSpeedMultiplier(0f); } StopAllRhinos(); if (showDebugLog) { Debug.Log("[RaftStartManager] 체력 0. 뗏목 구간 실패. 코뿔소 장애물 정지."); } } private void StartAllRhinos() { if (rhinos == null) return; foreach (RhinoObstacle rhino in rhinos) { if (rhino == null) continue; rhino.StartRhino(); } } private void StopAllRhinos() { if (rhinos == null) return; foreach (RhinoObstacle rhino in rhinos) { if (rhino == null) continue; rhino.StopRhino(); } } }