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

195 lines
4.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITFALL.Hotkey;
using BITKit;
using BITKit.Entities;
using BITKit.Entities.Player;
using BITKit.UX;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
using UnityEngine.UIElements;
namespace BITFALL.UX
{
public class UXRadialMenu : UIToolKitPanel
{
[SerializeReference, SubclassSelector] private IPlayerService playerService;
[SerializeField] private InputActionReference escapeAction;
[SerializeField] private InputActionReference radialMenuAction;
[SerializeField] private InputActionReference cancelAction;
[SerializeField] private VisualTreeAsset template;
[UXBindPath("radialMenu-container")]
private VisualElement _container;
[UXBindPath("info-label")]
private Label infoLabel;
[Inject]
private IHotkeyCollection _hotkeyCollection;
private IHotkeyProvider _currentHotkeyProvider;
private VisualElement _currentHotkeyDuration;
protected override void Start()
{
base.Start();
BITKit.UX.UXUtils.Inject(this);
_container.Clear();
playerService.OnPlayerInitialized += OnPlayerInitialized;
playerService.OnPlayerDisposed += OnPlayerDisposed;
}
private void OnPlayerDisposed(Entity obj)
{
_hotkeyCollection = null;
if(IsEntered)UXService.Return();
}
private void OnPlayerInitialized(Entity obj)
{
obj.Inject(this);
}
private static void OnEscape(InputAction.CallbackContext obj)
{
if (obj is { interaction: PressInteraction, performed: true })
UXService.Entry<UXHud>();
}
public override void OnUpdate(float deltaTime)
{
base.OnUpdate(deltaTime);
if (IsEntered is false) return;
if (_currentHotkeyProvider is not null)
{
var width = Mathf.Clamp(_currentHotkeyDuration.style.width.value.value + 100 * deltaTime / _currentHotkeyProvider.HoldDuration, 0, 100);
_currentHotkeyDuration.style.width =
new StyleLength(Length.Percent(width));
if (!(width >= 100)) return;
if (!_currentHotkeyProvider.Enabled) return;
_currentHotkeyProvider.OnPerform();
UXService.Return();
}
}
protected override void OnPanelEntry()
{
base.OnPanelEntry();
infoLabel.text = "选择快速动作";
var count = _hotkeyCollection.Hotkeys.Count();
if (count is 0)
{
infoLabel.text = "<color=yellow>目前没有快速动作</color>";
}
for (var i = 0; i < count; i++)
{
var hotkey = _hotkeyCollection.Hotkeys.ElementAt(i);
var angle = 360 / count * i;
var pos = Quaternion.Euler(0, 0, angle) * Vector3.up * 384;
pos.y *= 0.64f;
var container =new UXContainer( _container.Create<VisualElement>(template.CloneTree))
{
button =
{
text = hotkey.Name,
//label.style.backgroundColor = Color.red;
focusable = false,
clickable =hotkey.HoldDuration is 0 ? new Clickable(OnClick):null
},
visualElement = { style =
{
position = Position.Absolute,
},
transform =
{
position = pos,
}
}
};
container.visualElement.SetEnabled(hotkey.Enabled);
container.visualElement.RegisterCallback<MouseOverEvent>(OnMouseOver);
if (hotkey.HoldDuration > 0)
{
container.visualElement.RegisterCallback<MouseUpEvent>(OnMouseUp);
container.visualElement.RegisterCallback<MouseDownEvent>(OnMouseDown);
}
continue;
void OnClick()
{
if (hotkey.Enabled)
hotkey.OnPerform();
UXService.Return();
}
void OnMouseDown(MouseDownEvent evt)
{
_currentHotkeyProvider = hotkey;
_currentHotkeyDuration = container.visualElement.Q(UXConstant.ProcessBarFill);
}
void OnMouseUp(MouseUpEvent evt)
{
if (_currentHotkeyDuration is not null)
{
_currentHotkeyDuration.style.width = new StyleLength(Length.Percent(0));
}
_currentHotkeyProvider = null;
}
void OnMouseOver(MouseOverEvent evt)
{
infoLabel.text = hotkey.Description;
}
}
inputActionGroup.RegisterCallback(escapeAction, OnEscape);
inputActionGroup.RegisterCallback(radialMenuAction, OnRadialMenu);
inputActionGroup.RegisterCallback(cancelAction, OnEscape);
}
private void OnRadialMenu(InputAction.CallbackContext obj)
{
//if (playerService.LocalPlayer is null) return;
switch (obj)
{
case {interaction:HoldInteraction,canceled:true}:
UXService.Entry<UXHud>();
break;
}
}
protected override void OnPanelExit()
{
base.OnPanelExit();
_currentHotkeyProvider = null;
_currentHotkeyDuration = null;
_container.Clear();
inputActionGroup.UnRegisterCallback(escapeAction, OnEscape);
inputActionGroup.UnRegisterCallback(radialMenuAction, OnRadialMenu);
inputActionGroup.UnRegisterCallback(cancelAction, OnEscape);
}
}
}