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

358 lines
7.6 KiB
C#

using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
public class FishingGameManager : MonoBehaviour
{
public enum ResultType
{
Perfect,
Good,
Miss
}
[Header("References")]
[SerializeField] private FishingGaugeUI ui;
[SerializeField] private FishingRewardSystem rewardSystem;
[SerializeField] private FishingHapticManager haptic;
[SerializeField] private RotateUI centerIconRotate;
[Header("Pointer")]
[SerializeField] private float pointerAngle;
[SerializeField] private float pointerSpeed = 180f;
[SerializeField] private float minSpeed = 180f;
[SerializeField] private float maxSpeed = 450f;
[Header("Zone")]
[SerializeField] private float startZoneSize = 90f;
[SerializeField] private float zoneSize = 90f;
[SerializeField] private float minZoneSize = 30f;
[SerializeField] private float maxZoneSize = 120f;
[SerializeField] private float zoneCenter;
[Header("Rules")]
[SerializeField] private int requiredSuccesses = 3;
[SerializeField] private int allowedFails = 3;
[Header("Round Settings")]
[SerializeField] private float nextRoundDelay = 0.35f;
[SerializeField] private bool randomDirectionEachRound = true;
[SerializeField] private bool startOnAwake = true;
[Header("Debug")]
[SerializeField] private bool showDebugLog = true;
private int successCount;
private int failCount;
private bool clockwise = true;
private bool activeGame;
private bool inputLocked;
private Coroutine nextRoundRoutine;
private void Start()
{
if (startOnAwake)
{
StartFishing();
}
else
{
InitializeIdleUI();
}
}
private void Update()
{
if (!activeGame)
return;
if (inputLocked)
return;
RotatePointer();
}
private void InitializeIdleUI()
{
if (ui != null)
{
ui.HideRoundResult();
ui.HideFinalResult();
ui.UpdateCounter(0, requiredSuccesses, 0, allowedFails);
ui.SetPointerRotation(0f);
ui.SetZone(0f, startZoneSize);
}
if (centerIconRotate != null)
centerIconRotate.StopRotate();
}
public void StartFishing()
{
if (nextRoundRoutine != null)
{
StopCoroutine(nextRoundRoutine);
nextRoundRoutine = null;
}
successCount = 0;
failCount = 0;
pointerAngle = 0f;
pointerSpeed = minSpeed;
zoneSize = startZoneSize;
activeGame = true;
inputLocked = false;
clockwise = Random.value > 0.5f;
if (ui != null)
{
ui.HideRoundResult();
ui.HideFinalResult();
}
if (centerIconRotate != null)
{
centerIconRotate.ResetRotation();
centerIconRotate.StartRotate();
}
RandomizeZone();
UpdateUI();
if (showDebugLog)
Debug.Log("낚시 시작");
}
private void RotatePointer()
{
float dir = clockwise ? 1f : -1f;
pointerAngle += dir * pointerSpeed * Time.deltaTime;
pointerAngle = Normalize(pointerAngle);
if (ui != null)
ui.SetPointerRotation(pointerAngle);
}
public void SubmitAttempt()
{
if (!activeGame)
return;
if (inputLocked)
return;
inputLocked = true;
ResultType result = EvaluateResult();
switch (result)
{
case ResultType.Perfect:
OnPerfect();
break;
case ResultType.Good:
OnGood();
break;
case ResultType.Miss:
OnMiss();
break;
}
if (successCount >= requiredSuccesses)
{
FishingSuccess();
return;
}
if (failCount >= allowedFails)
{
FishingFail();
return;
}
nextRoundRoutine = StartCoroutine(NextRoundRoutine());
}
private ResultType EvaluateResult()
{
float delta = Mathf.Abs(Mathf.DeltaAngle(pointerAngle, zoneCenter));
float perfectRange = zoneSize * 0.2f;
float goodRange = zoneSize * 0.5f;
if (delta <= perfectRange)
return ResultType.Perfect;
if (delta <= goodRange)
return ResultType.Good;
return ResultType.Miss;
}
private void OnPerfect()
{
successCount++;
zoneSize *= 0.9f;
pointerSpeed *= 1.05f;
if (haptic != null)
haptic.Perfect();
if (ui != null)
ui.ShowResult("완벽!");
if (showDebugLog)
Debug.Log("낚시 판정: Perfect");
ClampDifficulty();
UpdateUI();
}
private void OnGood()
{
successCount++;
zoneSize *= 0.95f;
pointerSpeed *= 1.02f;
if (haptic != null)
haptic.Good();
if (ui != null)
ui.ShowResult("성공!");
if (showDebugLog)
Debug.Log("낚시 판정: Good");
ClampDifficulty();
UpdateUI();
}
private void OnMiss()
{
failCount++;
zoneSize *= 1.05f;
pointerSpeed *= 0.95f;
if (haptic != null)
haptic.Miss();
if (ui != null)
ui.ShowResult("실패!");
if (showDebugLog)
Debug.Log("낚시 판정: Miss");
ClampDifficulty();
UpdateUI();
}
private IEnumerator NextRoundRoutine()
{
yield return new WaitForSeconds(nextRoundDelay);
if (!activeGame)
yield break;
if (randomDirectionEachRound)
clockwise = Random.value > 0.5f;
RandomizeZone();
UpdateUI();
inputLocked = false;
nextRoundRoutine = null;
}
private void ClampDifficulty()
{
zoneSize = Mathf.Clamp(zoneSize, minZoneSize, maxZoneSize);
pointerSpeed = Mathf.Clamp(pointerSpeed, minSpeed, maxSpeed);
}
private void RandomizeZone()
{
zoneCenter = Random.Range(0f, 360f);
}
private void UpdateUI()
{
if (ui == null)
return;
ui.SetZone(zoneCenter, zoneSize);
ui.UpdateCounter(successCount, requiredSuccesses, failCount, allowedFails);
}
private void FishingSuccess()
{
activeGame = false;
inputLocked = true;
if (centerIconRotate != null)
centerIconRotate.StopRotate();
if (ui != null)
ui.ShowFinalResult("낚시 성공!");
if (rewardSystem != null)
rewardSystem.GiveReward();
if (showDebugLog)
Debug.Log("낚시 최종 성공");
}
private void FishingFail()
{
activeGame = false;
inputLocked = true;
if (centerIconRotate != null)
centerIconRotate.StopRotate();
if (ui != null)
ui.ShowFinalResult("낚시 실패!");
if (showDebugLog)
Debug.Log("낚시 최종 실패");
}
public void ResetFishing()
{
StartFishing();
}
private float Normalize(float angle)
{
angle %= 360f;
if (angle < 0f)
angle += 360f;
return angle;
}
// XR Input Action의 Select / Trigger 버튼에 연결
public void OnSubmit(InputValue value)
{
if (value.isPressed)
SubmitAttempt();
}
// Reset 버튼에 연결 가능
public void OnReset(InputValue value)
{
if (value.isPressed)
ResetFishing();
}
}