BITFALL/Assets/Artists/Scripts/UX/UXHud.cs

181 lines
6.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using BITFALL.Entities.Armor;
using BITFALL.Player.Equip;
using BITFALL.Player.Movement;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEngine.InputSystem;
using BITKit;
using BITKit.UX;
using BITKit.Entities;
using BITKit.Entities.Player;
using BITKit.SceneManagement;
using BITKit.Selection;
using BITKit.Steamwork;
using UnityEditor;
using UnityEngine.InputSystem.Interactions;
namespace BITFALL.UX
{
public class UXHud : UIToolKitPanel
{
[Header(Constant.Header.Providers)]
[SerializeReference, SubclassSelector] private ISceneService sceneService;
[SerializeReference, SubclassSelector] private IPlayerService playerService;
[SerializeReference, SubclassSelector] private ISteamService steamService;
[Header(Constant.Header.Components)]
[SerializeField] private UXLabel seleableLabel;
[SerializeField] private UXImage crosshairImage;
[SerializeField] private UXImage crosshairParentImage;
[SerializeField] private UXLabel playerNameLabel;
[SerializeField] private UXImage playerAvatarImage;
[SerializeField] private UXElement playerInfo;
[SerializeField] private UXBar healthBar;
[SerializeField] private UXBar lerpHealthBar;
[SerializeField] private UXBar staminaBar;
[SerializeField] private UXBar armorBar;
[Header(Constant.Header.Input)]
[SerializeField] private InputActionReference inventoryAction;
[SerializeField] private InputActionReference returnAction;
[Inject]
private IHealth _health;
[Inject]
private IEntityMovement _entityMovement;
[Inject]
private IPlayerMovement _playerMovement;
[Inject]
private IEquipService _equipService;
[Inject]
private ISelector _selector;
[Inject]
private IArmor _armor;
private float _currentHealthLerp;
protected override void Awake()
{
base.Awake();
seleableLabel.SetActive(false);
inputActionGroup.RegisterCallback(returnAction, OnReturn);
inputActionGroup.RegisterCallback(inventoryAction, OnInventory);
sceneService.OnSceneLoaded += x=>Entry();
playerService.OnPlayerInitialized += OnPlayerInitializedLocalPlayer;
}
private void OnDestroy()
{
playerService.OnPlayerInitialized -= OnPlayerInitializedLocalPlayer;
}
public void OnActive(ISelectable selectable)
{
seleableLabel.SetActive(false);
}
public void OnSelect(ISelectable selectable)
{
seleableLabel.SetActive(true);
seleableLabel.Set(selectable.Transform.TryGetComponent<IDescription>(out var description)
? description.Name
: "互动");
}
public void OnInactive(ISelectable selectable)
{
seleableLabel.SetActive(false);
}
private async void OnPlayerInitializedLocalPlayer(IEntity entity)
{
entity.Inject(this);
_health.OnSetAlive += OnSetAlive;
_health.OnSetHealthPoint += OnSetHP;
_selector.OnActive += OnActive;
_selector.OnInactive += OnInactive;
_selector.OnSelected += OnSelect;
_armor.OnArmorChanged += x => armorBar.Set(x);
_armor.OnEquipArmor += x =>
{
armorBar.Set(_armor.Armor);
armorBar.SetActive(true);
};
_armor.OnUnEquipArmor += x => armorBar.SetActive(false);
if (steamService.IsInitialized)
{
playerNameLabel.Set(steamService.Name);
var avatar = await steamService.GetAvatarAsync(cancellationToken);
playerAvatarImage.SetTexture(avatar);
}
_equipService = entity.Get<IEquipService>();
armorBar.SetActive(_armor.TryGetCurrentArmor(out _));
OnSetHP(_health.HealthPoint);
OnSetAlive(_health.IsAlive);
OnInactive(null);
}
private void OnInventory(InputAction.CallbackContext context)
{
if(playerService.LocalPlayer is null) return;
if(_health.IsAlive is false) return;
if(context is {interaction:PressInteraction,performed:true})
UXService.Entry<UXInventory>();
}
private void Update()
{
if (_health is not null)
{
_currentHealthLerp = Mathf.MoveTowards(_currentHealthLerp, _health.HealthPoint * 0.01f, Time.deltaTime * 5).Fix();
_currentHealthLerp = Mathf.Clamp(_currentHealthLerp, 0, 1);
lerpHealthBar.SetDirect(_currentHealthLerp,_health.HealthPoint.ToString());
staminaBar.Set(_playerMovement.Stamina * 0.01f);
staminaBar.visualElement.parent.SetActive(_playerMovement.Stamina is not 100);
}
}
private void LateUpdate()
{
if (playerService.LocalPlayer is null) return;
crosshairImage.SetPosition(_entityMovement.ViewCenter + _entityMovement.ViewRotation * Vector3.forward);
if(_equipService is null) return;
var currentCrosshairOpacity = crosshairParentImage.visualElement.style.opacity.value;
crosshairParentImage.visualElement.style.opacity = Mathf.Lerp(currentCrosshairOpacity, _equipService.Zoom.Allow ? 0 : 1, Time.deltaTime * 5);
}
private static void OnReturn(InputAction.CallbackContext context)
{
if (context.JustPressed())
UXService.Entry<UXMenu>();
}
private void OnSetAlive(bool alive)
{
if (alive is false)
{
Entry();
}
crosshairImage.SetActive(alive);
crosshairParentImage.SetActive(alive);
playerInfo.SetActive(alive);
}
private void OnSetHP(int hp)
{
healthBar.Set(Mathf.Clamp(hp,0,100) * 0.01f);
}
}
}