354 lines
9.5 KiB
C#
354 lines
9.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.InputSystem;
|
|
|
|
public class ShellGameManager : MonoBehaviour
|
|
{
|
|
[Header("References")]
|
|
[SerializeField] private PlayerMovement player;
|
|
[SerializeField] private UIManager ui;
|
|
[SerializeField] private ShellController shellController;
|
|
|
|
[Header("Shell Target")]
|
|
[Tooltip("조개 전체 Transform 또는 보상 위치 Transform을 넣으세요.")]
|
|
[SerializeField] private Transform shell;
|
|
|
|
[Header("Reward Settings")]
|
|
[SerializeField] private float collectDistance = 1.5f;
|
|
[SerializeField] private bool failWhenClosed = true;
|
|
|
|
[Header("VR Distance Option")]
|
|
[Tooltip("VR에서는 플레이어 머리 높이 때문에 Y축 거리를 무시하는 것이 안정적입니다.")]
|
|
[SerializeField] private bool ignoreHeight = true;
|
|
|
|
[Header("Input Actions")]
|
|
[Tooltip("오른손 Trigger 또는 XRI RightHand Interaction / Activate 액션을 연결하세요.")]
|
|
[SerializeField] private InputActionReference collectAction;
|
|
|
|
[Tooltip("선택 사항입니다. 리셋 버튼 액션을 연결하고 싶을 때 사용합니다.")]
|
|
[SerializeField] private InputActionReference resetAction;
|
|
|
|
[Header("Events")]
|
|
[SerializeField] private UnityEvent onSuccess;
|
|
[SerializeField] private UnityEvent onFail;
|
|
|
|
[Header("Debug")]
|
|
[SerializeField] private bool showDebugLog = true;
|
|
|
|
private bool gameFinished;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] OnEnable 실행됨");
|
|
|
|
RegisterInputActions();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] OnDisable 실행됨");
|
|
|
|
UnregisterInputActions();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] Start 실행됨 / ResetGame 호출");
|
|
|
|
ResetGame();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
UpdateUI();
|
|
}
|
|
|
|
private void RegisterInputActions()
|
|
{
|
|
if (collectAction == null)
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] Collect Action이 연결되지 않았습니다.");
|
|
}
|
|
else if (collectAction.action == null)
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] Collect Action 안의 action이 null입니다.");
|
|
}
|
|
else
|
|
{
|
|
collectAction.action.performed += OnCollectPerformed;
|
|
collectAction.action.Enable();
|
|
|
|
if (showDebugLog)
|
|
{
|
|
Debug.Log(
|
|
$"[ShellGameManager] Collect Action 등록 완료: {collectAction.action.name} / Enabled: {collectAction.action.enabled}"
|
|
);
|
|
}
|
|
}
|
|
|
|
if (resetAction != null && resetAction.action != null)
|
|
{
|
|
resetAction.action.performed += OnResetPerformed;
|
|
resetAction.action.Enable();
|
|
|
|
if (showDebugLog)
|
|
{
|
|
Debug.Log(
|
|
$"[ShellGameManager] Reset Action 등록 완료: {resetAction.action.name} / Enabled: {resetAction.action.enabled}"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UnregisterInputActions()
|
|
{
|
|
if (collectAction != null && collectAction.action != null)
|
|
{
|
|
collectAction.action.performed -= OnCollectPerformed;
|
|
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] Collect Action 등록 해제");
|
|
}
|
|
|
|
if (resetAction != null && resetAction.action != null)
|
|
{
|
|
resetAction.action.performed -= OnResetPerformed;
|
|
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] Reset Action 등록 해제");
|
|
}
|
|
}
|
|
|
|
private void UpdateUI()
|
|
{
|
|
if (ui == null)
|
|
return;
|
|
|
|
if (player != null)
|
|
{
|
|
ui.SetControl(player.IsReversed);
|
|
ui.SetMovementDebug(player.CurrentInput, player.CurrentOutput);
|
|
}
|
|
|
|
if (shellController != null)
|
|
{
|
|
ui.SetShellState(shellController.IsOpen);
|
|
ui.SetShellTimer(shellController.StateTimer01, shellController.IsOpen);
|
|
}
|
|
|
|
if (!gameFinished)
|
|
UpdatePromptUI();
|
|
}
|
|
|
|
private void UpdatePromptUI()
|
|
{
|
|
if (ui == null || player == null || shell == null || shellController == null)
|
|
return;
|
|
|
|
float distance = GetDistance(player.transform.position, shell.position);
|
|
|
|
if (distance > collectDistance)
|
|
{
|
|
ui.SetPromptFarFromShell();
|
|
}
|
|
else
|
|
{
|
|
ui.SetPromptNearShell(shellController.IsOpen);
|
|
}
|
|
}
|
|
|
|
public void TryCollectReward()
|
|
{
|
|
Debug.Log("[ShellGameManager] TryCollectReward 실행됨");
|
|
|
|
if (gameFinished)
|
|
{
|
|
Debug.Log("[ShellGameManager] 이미 게임이 끝난 상태라 입력을 무시합니다.");
|
|
return;
|
|
}
|
|
|
|
if (player == null)
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] Player 참조가 비어 있습니다.");
|
|
return;
|
|
}
|
|
|
|
if (shell == null)
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] Shell Transform 참조가 비어 있습니다.");
|
|
return;
|
|
}
|
|
|
|
if (shellController == null)
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] ShellController 참조가 비어 있습니다.");
|
|
return;
|
|
}
|
|
|
|
float distance = GetDistance(player.transform.position, shell.position);
|
|
|
|
Debug.Log(
|
|
$"[ShellGameManager] 판정 정보 / 거리: {distance:F2} / 성공 가능 거리: {collectDistance:F2} / 조개 열림: {shellController.IsOpen} / FailWhenClosed: {failWhenClosed}"
|
|
);
|
|
|
|
if (distance > collectDistance)
|
|
{
|
|
if (ui != null)
|
|
ui.SetPromptFarFromShell();
|
|
|
|
Debug.Log("[ShellGameManager] 조개와 너무 멀어서 보상을 획득할 수 없습니다.");
|
|
return;
|
|
}
|
|
|
|
if (shellController.IsOpen)
|
|
{
|
|
Debug.Log("[ShellGameManager] 성공 조건 만족: 조개 근처 + 조개 열림");
|
|
Success();
|
|
}
|
|
else
|
|
{
|
|
if (failWhenClosed)
|
|
{
|
|
Debug.Log("[ShellGameManager] 실패 조건 만족: 조개 근처 + 조개 닫힘");
|
|
Fail();
|
|
}
|
|
else
|
|
{
|
|
if (ui != null)
|
|
ui.SetPromptNearShell(false);
|
|
|
|
Debug.Log("[ShellGameManager] 조개가 닫혀 있어서 아직 획득할 수 없습니다. FailWhenClosed가 꺼져 있습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
private float GetDistance(Vector3 a, Vector3 b)
|
|
{
|
|
if (ignoreHeight)
|
|
{
|
|
a.y = 0f;
|
|
b.y = 0f;
|
|
}
|
|
|
|
return Vector3.Distance(a, b);
|
|
}
|
|
|
|
private void Success()
|
|
{
|
|
gameFinished = true;
|
|
|
|
if (ui != null)
|
|
{
|
|
ui.ShowReward(true);
|
|
Debug.Log("[ShellGameManager] UIManager.ShowReward(true) 호출됨");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] UI 참조가 비어 있어서 성공 UI를 표시할 수 없습니다.");
|
|
}
|
|
|
|
onSuccess?.Invoke();
|
|
|
|
Debug.Log("[ShellGameManager] SUCCESS! 조개가 열린 타이밍에 보상을 획득했습니다.");
|
|
}
|
|
|
|
private void Fail()
|
|
{
|
|
gameFinished = true;
|
|
|
|
if (ui != null)
|
|
{
|
|
ui.ShowReward(false);
|
|
Debug.Log("[ShellGameManager] UIManager.ShowReward(false) 호출됨");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] UI 참조가 비어 있어서 실패 UI를 표시할 수 없습니다.");
|
|
}
|
|
|
|
onFail?.Invoke();
|
|
|
|
Debug.Log("[ShellGameManager] FAIL! 조개가 닫힌 타이밍에 시도했습니다.");
|
|
}
|
|
|
|
public void ResetGame()
|
|
{
|
|
gameFinished = false;
|
|
|
|
if (ui != null)
|
|
{
|
|
ui.HideReward();
|
|
ui.SetPromptDefault();
|
|
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] UI 초기화 완료");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] UI 참조가 비어 있습니다.");
|
|
}
|
|
|
|
if (shellController != null)
|
|
{
|
|
shellController.ResetShell();
|
|
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] ShellController.ResetShell 호출됨");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[ShellGameManager] ShellController 참조가 비어 있습니다.");
|
|
}
|
|
|
|
if (showDebugLog)
|
|
Debug.Log("[ShellGameManager] ResetGame 완료");
|
|
}
|
|
|
|
private void OnCollectPerformed(InputAction.CallbackContext context)
|
|
{
|
|
Debug.Log(
|
|
$"[ShellGameManager] Collect Action 입력됨 / Action: {context.action.name} / Control: {context.control?.path} / Phase: {context.phase}"
|
|
);
|
|
|
|
TryCollectReward();
|
|
}
|
|
|
|
private void OnResetPerformed(InputAction.CallbackContext context)
|
|
{
|
|
Debug.Log(
|
|
$"[ShellGameManager] Reset Action 입력됨 / Action: {context.action.name} / Control: {context.control?.path} / Phase: {context.phase}"
|
|
);
|
|
|
|
ResetGame();
|
|
}
|
|
|
|
// PlayerInput Send Messages 방식을 쓸 때도 호환되게 남겨둔 함수입니다.
|
|
public void OnCollect(InputValue value)
|
|
{
|
|
Debug.Log("[ShellGameManager] OnCollect(InputValue) 호출됨");
|
|
|
|
if (value.isPressed)
|
|
{
|
|
Debug.Log("[ShellGameManager] OnCollect 입력 Pressed 상태");
|
|
TryCollectReward();
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("[ShellGameManager] OnCollect 입력이 Pressed 상태가 아님");
|
|
}
|
|
}
|
|
|
|
public void OnReset(InputValue value)
|
|
{
|
|
Debug.Log("[ShellGameManager] OnReset(InputValue) 호출됨");
|
|
|
|
if (value.isPressed)
|
|
{
|
|
Debug.Log("[ShellGameManager] OnReset 입력 Pressed 상태");
|
|
ResetGame();
|
|
}
|
|
}
|
|
} |