2025-12-05 19:04:53 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using TMPro;
|
|
|
|
|
|
using UnityEngine;
|
2025-12-05 20:57:29 +08:00
|
|
|
|
using UnityEngine.InputSystem;
|
2025-12-17 20:03:29 +08:00
|
|
|
|
using UnityEngine.U2D;
|
2025-12-05 19:04:53 +08:00
|
|
|
|
|
2025-12-09 20:31:44 +08:00
|
|
|
|
namespace AlicizaX.InputGlyph
|
2025-12-05 19:04:53 +08:00
|
|
|
|
{
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class GlyphEntry
|
|
|
|
|
|
{
|
|
|
|
|
|
public Sprite Sprite;
|
2025-12-05 20:57:29 +08:00
|
|
|
|
public InputAction action;
|
2025-12-05 19:04:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class DeviceGlyphTable
|
|
|
|
|
|
{
|
2025-12-17 20:03:29 +08:00
|
|
|
|
// Table 名称(序列化)
|
2025-12-10 17:38:31 +08:00
|
|
|
|
public string deviceName;
|
2025-12-17 20:03:29 +08:00
|
|
|
|
|
|
|
|
|
|
// 支持三种来源:
|
|
|
|
|
|
// 1) TMP Sprite Asset(TextMeshPro sprite asset)
|
2025-12-05 19:04:53 +08:00
|
|
|
|
public TMP_SpriteAsset tmpAsset;
|
2025-12-17 20:03:29 +08:00
|
|
|
|
|
|
|
|
|
|
// 2) Unity SpriteAtlas(可选)
|
|
|
|
|
|
public SpriteAtlas spriteAtlas;
|
|
|
|
|
|
|
|
|
|
|
|
// 3) Texture2D(Sprite Mode = Multiple),在 Sprite Editor 切好的切片
|
|
|
|
|
|
public Texture2D spriteSheetTexture;
|
|
|
|
|
|
|
2025-12-05 19:04:53 +08:00
|
|
|
|
public List<GlyphEntry> entries = new List<GlyphEntry>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[CreateAssetMenu(fileName = "InputGlyphDatabase", menuName = "InputGlyphs/InputGlyphDatabase", order = 400)]
|
|
|
|
|
|
public class InputGlyphDatabase : ScriptableObject
|
|
|
|
|
|
{
|
|
|
|
|
|
public List<DeviceGlyphTable> tables = new List<DeviceGlyphTable>();
|
|
|
|
|
|
|
2025-12-10 17:38:31 +08:00
|
|
|
|
// 当 FindEntryByControlPath 传空 path 时返回的占位 sprite
|
|
|
|
|
|
public Sprite placeholderSprite;
|
|
|
|
|
|
|
|
|
|
|
|
public DeviceGlyphTable GetTable(string deviceName)
|
2025-12-05 19:04:53 +08:00
|
|
|
|
{
|
2025-12-10 17:38:31 +08:00
|
|
|
|
if (string.IsNullOrEmpty(deviceName)) return null;
|
2025-12-05 19:04:53 +08:00
|
|
|
|
if (tables == null) return null;
|
2025-12-09 20:31:44 +08:00
|
|
|
|
for (int i = 0; i < tables.Count; ++i)
|
2025-12-10 17:38:31 +08:00
|
|
|
|
{
|
|
|
|
|
|
var t = tables[i];
|
|
|
|
|
|
if (t == null) continue;
|
|
|
|
|
|
if (string.Equals(t.deviceName, deviceName, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
|
return t;
|
|
|
|
|
|
}
|
2025-12-05 19:04:53 +08:00
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-17 20:03:29 +08:00
|
|
|
|
// 兼容枚举版本(示例)
|
2025-12-10 17:38:31 +08:00
|
|
|
|
public DeviceGlyphTable GetTable(InputDeviceWatcher.InputDeviceCategory device)
|
|
|
|
|
|
{
|
|
|
|
|
|
string name = "Other";
|
|
|
|
|
|
switch (device)
|
|
|
|
|
|
{
|
|
|
|
|
|
case InputDeviceWatcher.InputDeviceCategory.Keyboard: name = "Keyboard"; break;
|
|
|
|
|
|
case InputDeviceWatcher.InputDeviceCategory.Xbox: name = "Xbox"; break;
|
|
|
|
|
|
case InputDeviceWatcher.InputDeviceCategory.PlayStation: name = "PlayStation"; break;
|
2025-12-17 20:03:29 +08:00
|
|
|
|
default: name = "Xbox"; break;
|
2025-12-10 17:38:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
return GetTable(name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Sprite FindSprite(string controlPath, InputDeviceWatcher.InputDeviceCategory device)
|
|
|
|
|
|
{
|
|
|
|
|
|
var entry = FindEntryByControlPath(controlPath, device);
|
|
|
|
|
|
if (string.IsNullOrEmpty(controlPath) || entry == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return placeholderSprite;
|
|
|
|
|
|
}
|
|
|
|
|
|
return entry.Sprite;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 19:04:53 +08:00
|
|
|
|
public GlyphEntry FindEntryByControlPath(string controlPath, InputDeviceWatcher.InputDeviceCategory device)
|
|
|
|
|
|
{
|
|
|
|
|
|
var t = GetTable(device);
|
|
|
|
|
|
if (t != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < t.entries.Count; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
var e = t.entries[i];
|
2025-12-10 17:38:31 +08:00
|
|
|
|
if (e == null) continue;
|
|
|
|
|
|
if (e.action == null) continue;
|
|
|
|
|
|
if (e.action.bindings.Count <= 0) continue;
|
|
|
|
|
|
foreach (var binding in e.action.bindings)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.Equals(controlPath, binding.path, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
|
{
|
|
|
|
|
|
return e;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-05 19:04:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|