AlicizaX/Client/Assets/InputGlyph/TestRebindScript.cs
2025-12-26 15:39:41 +08:00

151 lines
4.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// TestRebindScript.cs
using System;
using System.Threading.Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using InputRemapper;
using UnityEngine.UI;
/// <summary>
/// 测试用不需要繁琐处理
/// </summary>
public class TestRebindScript : MonoBehaviour
{
[Header("UI")] public UXButton btn;
public TextMeshProUGUI bindKeyText;
public Image targetImage;
[Tooltip("如果不使用 actionReference则用 name 在全局 manager 查找")]
public string actionName = "movement";
[Header("Optional composite part (WASD style)")] [Tooltip("如果需要绑定 composite 的某一部分(例如 Up/Down/Left/Right填这个留空表示绑定非 composite 或整体 binding")]
public string compositePartName = "";
[Header("Behavior")] [Tooltip("如果 true在 Prepare 后自动调用 ConfirmApply() 并保存;否则等待手动 ConfirmPrepared()/CancelPrepared()")]
public bool autoConfirm = false;
private IDisposable prepareSub;
private IDisposable applySub;
private IDisposable rebindEndSub;
private void Start()
{
if (btn != null) btn.onClick.AddListener(OnBtnClicked);
InputDeviceWatcher.OnDeviceChanged += OnDeviceChanged;
UpdateBindingText();
if (InputBindingManager.Instance != null)
{
prepareSub = InputBindingManager.Instance.OnRebindPrepare.Subscribe(ctx =>
{
if (IsTargetContext(ctx))
{
var disp = ctx.overridePath == InputBindingManager.NULL_BINDING ? "<Cleared>" : ctx.overridePath;
bindKeyText.text = disp;
if (autoConfirm) _ = ConfirmPreparedAsync();
}
});
applySub = InputBindingManager.Instance.OnApply.Subscribe(_ => UpdateBindingText());
rebindEndSub = InputBindingManager.Instance.OnRebindEnd.Subscribe(_ => UpdateBindingText());
}
}
private void OnDisable()
{
if (btn != null) btn.onClick.RemoveListener(OnBtnClicked);
InputDeviceWatcher.OnDeviceChanged -= OnDeviceChanged;
prepareSub?.Dispose();
applySub?.Dispose();
rebindEndSub?.Dispose();
}
private void OnDeviceChanged(InputDeviceWatcher.InputDeviceCategory _)
{
UpdateBindingText();
}
private InputAction GetAction()
{
return InputBindingManager.Action(actionName);
}
private bool IsTargetContext(InputRemapper.InputBindingManager.RebindContext ctx)
{
if (ctx == null || ctx.action == null) return false;
var action = GetAction();
if (action == null) return false;
return ctx.action == action;
}
private void OnBtnClicked()
{
// Use manager API (we pass part name so manager can pick proper binding if needed)
InputBindingManager.StartRebind(actionName, string.IsNullOrEmpty(compositePartName) ? null : compositePartName);
}
public async void ConfirmPrepared()
{
bool ok = await ConfirmPreparedAsync();
if (!ok) Debug.LogError("ConfirmPrepared: apply failed.");
}
private async Task<bool> ConfirmPreparedAsync()
{
try
{
var task = InputBindingManager.ConfirmApply();
if (task == null) return false;
return await task;
}
catch (Exception ex)
{
Debug.LogError(ex);
return false;
}
}
public void CancelPrepared()
{
InputBindingManager.DiscardPrepared();
UpdateBindingText();
}
private void UpdateBindingText()
{
var action = GetAction();
if (action == null)
{
bindKeyText.text = "<no action>";
if (targetImage != null) targetImage.sprite = null;
return;
}
string disp = GlyphService.GetBindingControlPath(action, InputDeviceWatcher.CurrentCategory);
bindKeyText.text = GlyphService.GetDisplayNameFromInputAction(action);
try
{
var deviceCat = InputDeviceWatcher.CurrentCategory;
string controlPath = GlyphService.GetBindingControlPath(action, deviceCat);
if (!string.IsNullOrEmpty(controlPath) && GlyphService.TryGetUISpriteForActionPath(controlPath, deviceCat, out Sprite sprite))
{
if (targetImage != null) targetImage.sprite = sprite;
}
else
{
if (targetImage != null) targetImage.sprite = null;
}
}
catch
{
if (targetImage != null) targetImage.sprite = null;
}
}
}