using System; using System.Linq; using AlicizaX.InputGlyph; using UnityEngine; using UnityEngine.InputSystem; public static class GlyphService { /// /// 可选的全局数据库引用。你可以通过场景内的启动组件在 Awake 时赋值, /// 或者在调用每个方法时传入 InputGlyphDatabase 参数(见方法签名)。 /// public static InputGlyphDatabase Database { get { if (_database == null) { _database = Resources.Load("InputGlyphDatabase"); } return _database; } } private static InputGlyphDatabase _database; public static string GetBindingControlPath(InputAction action, InputDeviceWatcher.InputDeviceCategory? deviceOverride = null) { if (action == null) return string.Empty; var binding = GetBindingControl(action, deviceOverride); return binding.hasOverrides ? binding.effectivePath : binding.path; } public static bool TryGetTMPTagForActionPath(InputActionReference reference, InputDeviceWatcher.InputDeviceCategory device, out string tag, out string displayFallback, InputGlyphDatabase db = null) { string path = GetBindingControlPath(reference, device); return TryGetTMPTagForActionPath(path, device, out tag, out displayFallback, db); } public static bool TryGetUISpriteForActionPath(InputActionReference reference, InputDeviceWatcher.InputDeviceCategory device, out Sprite sprite, InputGlyphDatabase db = null) { string path = GetBindingControlPath(reference, device); return TryGetUISpriteForActionPath(path, device, out sprite, db); } public static bool TryGetTMPTagForActionPath(string controlPath, InputDeviceWatcher.InputDeviceCategory device, out string tag, out string displayFallback, InputGlyphDatabase db = null) { tag = null; displayFallback = null; db = db ?? Database; displayFallback = GetDisplayNameFromControlPath(controlPath); var sprite = db.FindSprite(controlPath, device) ?? db.FindSprite(controlPath, InputDeviceWatcher.InputDeviceCategory.Keyboard); var spriteName = sprite == null ? string.Empty : sprite.name; tag = $""; return true; } public static bool TryGetUISpriteForActionPath(string controlPath, InputDeviceWatcher.InputDeviceCategory device, out Sprite sprite, InputGlyphDatabase db = null) { sprite = null; db = db ?? Database; if (string.IsNullOrEmpty(controlPath) || db == null) return false; sprite = db.FindSprite(controlPath, device) ?? db.FindSprite(controlPath, InputDeviceWatcher.InputDeviceCategory.Keyboard); return sprite != null; } static InputBinding GetBindingControl(InputAction action, InputDeviceWatcher.InputDeviceCategory? deviceOverride = null) { if (action == null) return default; var curCategory = deviceOverride ?? InputDeviceWatcher.CurrentCategory; var hints = GetDeviceHintsForCategory(curCategory); foreach (var binding in action.bindings) { var deviceName = binding.path ?? string.Empty; if (hints.Any(h => deviceName.IndexOf(h, StringComparison.OrdinalIgnoreCase) >= 0)) { return binding; } } return default; } static string[] GetDeviceHintsForCategory(InputDeviceWatcher.InputDeviceCategory cat) { switch (cat) { case InputDeviceWatcher.InputDeviceCategory.Keyboard: return new[] { "Keyboard", "Mouse" }; case InputDeviceWatcher.InputDeviceCategory.Xbox: return new[] { "XInput", "Xbox", "Gamepad" }; case InputDeviceWatcher.InputDeviceCategory.PlayStation: return new[] { "DualShock", "DualSense", "PlayStation", "Gamepad" }; default: return new[] { "XInput", "Xbox", "Gamepad" }; } } public static string GetDisplayNameFromInputAction(InputAction reference) { string controlPath = GetBindingControlPath(reference, InputDeviceWatcher.CurrentCategory); return GetDisplayNameFromControlPath(controlPath); } public static string GetDisplayNameFromControlPath(string controlPath) { if (string.IsNullOrEmpty(controlPath)) return string.Empty; var parts = controlPath.Split('/'); var last = parts[parts.Length - 1].Trim(new char[] { '{', '}', '<', '>', '\'', '"' }); return last; } }