Files
WhaleAdventure_VR/Assets/My project/shell Scripts/UI/ShellGameManager.cs
skrwns304@gmail.com b1e85a5b89 2026-06-19 UI, UI로직
2026-06-19 14:27:40 +09:00

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();
}
}
}