Files
Shopping_UnityVR/Assets/02_Scripts/Player/PlayerHunger.cs

101 lines
3.2 KiB
C#

using System;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit.Locomotion.Movement;
namespace VRShopping.Player
{
// 플레이어 허기 게이지. 시간이 지나면 깎이고 0이 되면 이동 속도가 느려진다.
// Complete XR Origin Set Up 루트에 부착 (PlayerWallet과 동일 위치).
public class PlayerHunger : MonoBehaviour
{
[Header("Gauge")]
[SerializeField, Min(0f)] private float _maxHunger = 100f;
[SerializeField, Min(0f)] private float _initialHunger = 80f;
[SerializeField, Min(0f)] private float _decayPerSecond = 1.5f;
[Header("Slow Penalty")]
// 굶주린 상태에서의 이동 속도 (원래 속도와 곱해지지 않고 절댓값으로 대체)
[SerializeField, Min(0f)] private float _starvedMoveSpeed = 0.6f;
// ContinuousMoveProvider의 서브클래스(예: Starter Assets의 DynamicMoveProvider)도 그대로 할당 가능
[SerializeField] private ContinuousMoveProvider _moveProvider;
// 0~_maxHunger 사이의 현재 값 (UI 갱신용 이벤트로 통지)
public event Action<float, float> OnHungerChanged; // (current, max)
public float Current { get; private set; }
public float Max => _maxHunger;
public bool IsStarved => Current <= 0f;
private float _originalMoveSpeed;
private bool _slowApplied;
private void Awake()
{
Current = Mathf.Clamp(_initialHunger, 0f, _maxHunger);
// MoveProvider 원본 속도 캐싱
if (_moveProvider != null) _originalMoveSpeed = _moveProvider.moveSpeed;
}
private void OnDestroy()
{
// 씬 종료 시 변경한 속도 복구
RestoreMoveSpeed();
}
private void Start()
{
OnHungerChanged?.Invoke(Current, _maxHunger);
}
private void Update()
{
if (Current > 0f)
{
Current = Mathf.Max(0f, Current - _decayPerSecond * Time.deltaTime);
OnHungerChanged?.Invoke(Current, _maxHunger);
}
UpdateSlowState();
}
// 시식 등으로 허기를 회복
public void Eat(float amount)
{
if (amount <= 0f) return;
Current = Mathf.Min(_maxHunger, Current + amount);
OnHungerChanged?.Invoke(Current, _maxHunger);
UpdateSlowState();
}
private void UpdateSlowState()
{
if (_moveProvider == null) return;
bool shouldSlow = IsStarved;
if (shouldSlow && !_slowApplied)
{
_moveProvider.moveSpeed = _starvedMoveSpeed;
_slowApplied = true;
}
else if (!shouldSlow && _slowApplied)
{
_moveProvider.moveSpeed = _originalMoveSpeed;
_slowApplied = false;
}
}
private void RestoreMoveSpeed()
{
if (_moveProvider != null && _slowApplied)
{
_moveProvider.moveSpeed = _originalMoveSpeed;
_slowApplied = false;
}
}
}
}