195 lines
4.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
|