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