feat: add reusable virtual hud input

This commit is contained in:
ud18010
2026-07-30 11:14:56 +08:00
parent 3546d16632
commit 5853c5bd83
26 changed files with 6403 additions and 31 deletions
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XGame.VirtualInput
{
public sealed class VirtualActionPad : MonoBehaviour
{
private readonly Dictionary<ActionButtonId, VirtualActionButton> buttons =
new Dictionary<ActionButtonId, VirtualActionButton>();
private RectTransform cancelArea;
public event Action<ActionButtonEvent> ButtonEvent;
private void Awake()
{
BindNodes();
}
private void OnDestroy()
{
foreach (VirtualActionButton button in buttons.Values)
{
if (button != null)
{
button.ButtonEvent -= OnChildButtonEvent;
}
}
buttons.Clear();
}
public VirtualActionButton GetButton(ActionButtonId id)
{
buttons.TryGetValue(id, out VirtualActionButton button);
return button;
}
public void SetCooldown(ActionButtonId id, float remainingSeconds, float durationSeconds)
{
VirtualActionButton button = GetButton(id);
if (button != null)
{
button.SetCooldown(remainingSeconds, durationSeconds);
}
}
public void SetCharges(ActionButtonId id, int count)
{
VirtualActionButton button = GetButton(id);
if (button != null)
{
button.SetCharges(count);
}
}
public void SetButtonEnabled(ActionButtonId id, bool enabled)
{
VirtualActionButton button = GetButton(id);
if (button != null)
{
button.SetButtonEnabled(enabled);
}
}
public void SetCancelAreaVisible(bool visible)
{
if (cancelArea != null)
{
cancelArea.gameObject.SetActive(visible);
}
}
private void BindNodes()
{
Transform cancel = transform.FindTransform("CancelArea");
cancelArea = cancel as RectTransform;
RegisterButton(ActionButtonId.Primary, "Btn_Primary");
RegisterButton(ActionButtonId.Skill1, "Btn_Skill1");
RegisterButton(ActionButtonId.Skill2, "Btn_Skill2");
RegisterButton(ActionButtonId.Skill3, "Btn_Skill3");
RegisterButton(ActionButtonId.Skill4, "Btn_Skill4");
SetCancelAreaVisible(false);
}
private void RegisterButton(ActionButtonId id, string childName)
{
Transform child = transform.FindTransform(childName);
if (child == null)
{
Debug.LogWarning("[VirtualActionPad] missing child button: " + childName, this);
return;
}
VirtualActionButton button = child.GetComponent<VirtualActionButton>();
if (button == null)
{
button = child.gameObject.AddComponent<VirtualActionButton>();
}
button.ButtonId = id;
button.SetCancelArea(cancelArea);
button.ButtonEvent -= OnChildButtonEvent;
button.ButtonEvent += OnChildButtonEvent;
buttons[id] = button;
}
private void OnChildButtonEvent(ActionButtonEvent evt)
{
if (evt.Phase == ActionButtonPhase.Drag || evt.Phase == ActionButtonPhase.HoldStart)
{
SetCancelAreaVisible(cancelArea != null);
}
else if (evt.Phase == ActionButtonPhase.Release || evt.Phase == ActionButtonPhase.Tap || evt.Phase == ActionButtonPhase.Cancel || evt.Phase == ActionButtonPhase.Blocked)
{
SetCancelAreaVisible(false);
}
ButtonEvent?.Invoke(evt);
}
}
}