육지도착
This commit is contained in:
238
Assets/02_Scripts/Cave/RaftStartManager.cs
Normal file
238
Assets/02_Scripts/Cave/RaftStartManager.cs
Normal file
@@ -0,0 +1,238 @@
|
||||
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<RaftRiverController>();
|
||||
|
||||
if (steeringKey == null)
|
||||
steeringKey = FindFirstObjectByType<SteeringKeyXR>();
|
||||
|
||||
if (raftHealth == null)
|
||||
raftHealth = FindFirstObjectByType<RaftHealth>();
|
||||
|
||||
if (rhinos == null || rhinos.Length == 0)
|
||||
rhinos = FindObjectsByType<RhinoObstacle>(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user