198 lines
6.9 KiB
C#
198 lines
6.9 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using OnlyScove.Scripts;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace UI
|
|
{
|
|
public class HUDController : MonoBehaviour
|
|
{
|
|
[Header("UI Document")]
|
|
public UIDocument hudDocument;
|
|
|
|
private VisualElement _healthFill;
|
|
private VisualElement _staminaFill;
|
|
private Label _healthText;
|
|
private VisualElement _interactionPrompt;
|
|
private Label _interactionLabel;
|
|
|
|
private VisualElement _statsArea;
|
|
private VisualElement _inventoryArea;
|
|
private VisualElement _infoArea;
|
|
|
|
private float _lastInputTime;
|
|
private bool _isHUDVisible = true;
|
|
public float autoHideDelay = 5f;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (hudDocument == null)
|
|
hudDocument = GetComponent<UIDocument>();
|
|
|
|
var root = hudDocument.rootVisualElement;
|
|
|
|
_healthFill = root.Q<VisualElement>("health-fill");
|
|
_staminaFill = root.Q<VisualElement>("stamina-fill");
|
|
_healthText = root.Q<Label>("health-text");
|
|
_interactionPrompt = root.Q<VisualElement>("interaction-prompt");
|
|
_interactionLabel = root.Q<Label>("interaction-text");
|
|
|
|
_statsArea = root.Q<VisualElement>("hud-stats");
|
|
_inventoryArea = root.Q<VisualElement>("hud-inventory");
|
|
_infoArea = root.Q<VisualElement>("hud-info");
|
|
|
|
_lastInputTime = Time.time;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (PlayerStateMachine.Local != null)
|
|
{
|
|
SubscribeToPlayer(PlayerStateMachine.Local);
|
|
}
|
|
|
|
HandleAutoHide();
|
|
HandleInventoryInput();
|
|
}
|
|
|
|
private void HandleAutoHide()
|
|
{
|
|
bool inputDetected = false;
|
|
|
|
// Check for mouse movement
|
|
if (Mouse.current != null && Mouse.current.delta.ReadValue().sqrMagnitude > 0.01f)
|
|
inputDetected = true;
|
|
|
|
// Check for any key press (including mouse buttons)
|
|
if (!inputDetected && Keyboard.current != null && Keyboard.current.anyKey.isPressed)
|
|
inputDetected = true;
|
|
|
|
if (!inputDetected && Mouse.current != null && (Mouse.current.leftButton.isPressed || Mouse.current.rightButton.isPressed))
|
|
inputDetected = true;
|
|
|
|
if (inputDetected)
|
|
{
|
|
_lastInputTime = Time.time;
|
|
SetHUDVisibility(true);
|
|
}
|
|
else if (Time.time - _lastInputTime > autoHideDelay)
|
|
{
|
|
SetHUDVisibility(false);
|
|
}
|
|
}
|
|
|
|
private void SetHUDVisibility(bool visible)
|
|
{
|
|
if (_isHUDVisible == visible) return;
|
|
_isHUDVisible = visible;
|
|
|
|
float targetOpacity = visible ? 1f : 0.2f;
|
|
|
|
_statsArea.style.opacity = targetOpacity;
|
|
_inventoryArea.style.opacity = targetOpacity;
|
|
_infoArea.style.opacity = targetOpacity;
|
|
|
|
_statsArea.style.transitionProperty = new List<StylePropertyName> { "opacity" };
|
|
_statsArea.style.transitionDuration = new List<TimeValue> { new TimeValue(0.5f, TimeUnit.Second) };
|
|
_inventoryArea.style.transitionProperty = new List<StylePropertyName> { "opacity" };
|
|
_inventoryArea.style.transitionDuration = new List<TimeValue> { new TimeValue(0.5f, TimeUnit.Second) };
|
|
_infoArea.style.transitionProperty = new List<StylePropertyName> { "opacity" };
|
|
_infoArea.style.transitionDuration = new List<TimeValue> { new TimeValue(0.5f, TimeUnit.Second) };
|
|
}
|
|
|
|
private void HandleInventoryInput()
|
|
{
|
|
if (Keyboard.current == null) return;
|
|
|
|
if (Keyboard.current.digit1Key.wasPressedThisFrame) SelectSlot(1);
|
|
if (Keyboard.current.digit2Key.wasPressedThisFrame) SelectSlot(2);
|
|
if (Keyboard.current.digit3Key.wasPressedThisFrame) SelectSlot(3);
|
|
}
|
|
|
|
private void SelectSlot(int index)
|
|
{
|
|
// Mock logic: Highlight the selected slot
|
|
var root = hudDocument.rootVisualElement;
|
|
for (int i = 1; i <= 3; i++)
|
|
{
|
|
var slot = root.Q<VisualElement>($"slot-{i}");
|
|
if (slot != null)
|
|
{
|
|
float width = (i == index) ? 2f : 1f;
|
|
Color color = (i == index) ? Color.white : new Color(0.5f, 0.5f, 0.5f);
|
|
|
|
slot.style.borderTopWidth = width;
|
|
slot.style.borderBottomWidth = width;
|
|
slot.style.borderLeftWidth = width;
|
|
slot.style.borderRightWidth = width;
|
|
|
|
slot.style.borderTopColor = color;
|
|
slot.style.borderBottomColor = color;
|
|
slot.style.borderLeftColor = color;
|
|
slot.style.borderRightColor = color;
|
|
}
|
|
}
|
|
_lastInputTime = Time.time;
|
|
SetHUDVisibility(true);
|
|
}
|
|
|
|
private PlayerStateMachine _currentPlayer;
|
|
|
|
private void SubscribeToPlayer(PlayerStateMachine player)
|
|
{
|
|
if (_currentPlayer == player) return;
|
|
|
|
if (_currentPlayer != null)
|
|
{
|
|
_currentPlayer.OnHealthChanged -= UpdateHealth;
|
|
_currentPlayer.OnStaminaChanged -= UpdateStamina;
|
|
_currentPlayer.OnInteractableTargetChanged -= UpdateInteraction;
|
|
}
|
|
|
|
_currentPlayer = player;
|
|
|
|
_currentPlayer.OnHealthChanged += UpdateHealth;
|
|
_currentPlayer.OnStaminaChanged += UpdateStamina;
|
|
_currentPlayer.OnInteractableTargetChanged += UpdateInteraction;
|
|
|
|
UpdateHealth(_currentPlayer.Health);
|
|
UpdateStamina(_currentPlayer.Stamina);
|
|
}
|
|
|
|
private void UpdateHealth(float health)
|
|
{
|
|
if (_healthFill != null) _healthFill.style.width = Length.Percent(health);
|
|
_lastInputTime = Time.time;
|
|
SetHUDVisibility(true);
|
|
}
|
|
|
|
private void UpdateStamina(float stamina)
|
|
{
|
|
if (_staminaFill != null) _staminaFill.style.width = Length.Percent(stamina);
|
|
if (stamina < 99f) // Only wake up HUD if stamina is being used
|
|
{
|
|
_lastInputTime = Time.time;
|
|
SetHUDVisibility(true);
|
|
}
|
|
}
|
|
|
|
private void UpdateInteraction(IInteractable interactable)
|
|
{
|
|
if (_interactionPrompt == null) return;
|
|
|
|
if (interactable != null)
|
|
{
|
|
_interactionPrompt.style.display = DisplayStyle.Flex;
|
|
if (_interactionLabel != null) _interactionLabel.text = interactable.InteractionPrompt;
|
|
_lastInputTime = Time.time;
|
|
SetHUDVisibility(true);
|
|
}
|
|
else
|
|
{
|
|
_interactionPrompt.style.display = DisplayStyle.None;
|
|
}
|
|
}
|
|
}
|
|
}
|