清理项目目录,引入 InputModule 做多平台输入适配
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
using SepCore.InputModule.Runtime;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SepCore.InputModule.Editor
|
||||
{
|
||||
[CustomEditor(typeof(InputModuleComponent))]
|
||||
public sealed class InputModuleComponentEditor : UnityEditor.Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
EditorGUILayout.Space(8);
|
||||
EditorGUILayout.HelpBox("Runtime state is only available in Play Mode.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
var component = (InputModuleComponent)target;
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Runtime State", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.Toggle("Initialized", component.IsInitialized);
|
||||
EditorGUILayout.EnumPopup("Device Kind", component.CurrentDeviceKind);
|
||||
EditorGUILayout.EnumPopup("Current Context", component.CurrentContext);
|
||||
EditorGUILayout.Toggle("Rebinding", component.IsRebinding);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 195d44e230bb20e40a011551390ea7f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,237 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using SepCore.InputModule.Runtime;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace SepCore.InputModule.Editor
|
||||
{
|
||||
public sealed class InputModuleDebugger : EditorWindow
|
||||
{
|
||||
private static readonly FieldInfo ContextStackField = typeof(InputModuleComponent).GetField("_contextStack", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
private static readonly FieldInfo ActionMapsField = typeof(InputModuleComponent).GetField("_actionMaps", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
private static readonly PropertyInfo StackItemsProperty = typeof(InputContextStack).GetProperty("Items", BindingFlags.Instance | BindingFlags.Public);
|
||||
private static readonly PropertyInfo StackCountProperty = typeof(InputContextStack).GetProperty("Count", BindingFlags.Instance | BindingFlags.Public);
|
||||
|
||||
private InputModuleComponent _target;
|
||||
private Vector2 _scrollPosition;
|
||||
private readonly Dictionary<InputContextId, bool> _mapFoldouts = new Dictionary<InputContextId, bool>();
|
||||
private double _nextRefresh;
|
||||
private const double RefreshInterval = 0.1;
|
||||
|
||||
[MenuItem("Window/Input Module Debugger")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<InputModuleDebugger>("Input Module");
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
double now = EditorApplication.timeSinceStartup;
|
||||
if (now >= _nextRefresh)
|
||||
{
|
||||
_nextRefresh = now + RefreshInterval;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
|
||||
|
||||
DrawHeader();
|
||||
DrawRuntimeStatus();
|
||||
DrawContextStack();
|
||||
DrawActionMaps();
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
private void DrawHeader()
|
||||
{
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.LabelField("Input Module Debugger", EditorStyles.largeLabel);
|
||||
EditorGUILayout.Space(4);
|
||||
}
|
||||
|
||||
private void DrawRuntimeStatus()
|
||||
{
|
||||
if (_target == null)
|
||||
{
|
||||
_target = FindInputModuleComponent();
|
||||
}
|
||||
|
||||
if (_target == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox("No InputModuleComponent found in the current scene.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Runtime Status", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.Toggle("Initialized", _target.IsInitialized);
|
||||
EditorGUILayout.EnumPopup("Device Kind", _target.CurrentDeviceKind);
|
||||
EditorGUILayout.EnumPopup("Current Context", _target.CurrentContext);
|
||||
EditorGUILayout.Toggle("Rebinding", _target.IsRebinding);
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
EditorGUILayout.Space(8);
|
||||
}
|
||||
|
||||
private void DrawContextStack()
|
||||
{
|
||||
if (_target == null || !_target.IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
object stack = ContextStackField?.GetValue(_target);
|
||||
if (stack == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int count = StackCountProperty != null ? (int)StackCountProperty.GetValue(stack) : 0;
|
||||
IReadOnlyList<InputContextId> items = StackItemsProperty?.GetValue(stack) as IReadOnlyList<InputContextId>;
|
||||
|
||||
EditorGUILayout.LabelField($"Context Stack (depth: {count})", EditorStyles.boldLabel);
|
||||
|
||||
if (items == null || count == 0)
|
||||
{
|
||||
EditorGUILayout.LabelField(" (empty)", EditorStyles.miniLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
bool isTop = i == items.Count - 1;
|
||||
string prefix = isTop ? "▶" : " ";
|
||||
GUIStyle style = isTop ? EditorStyles.label : EditorStyles.miniLabel;
|
||||
EditorGUILayout.LabelField($" {prefix} [{i}] {items[i]}", style);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(8);
|
||||
}
|
||||
|
||||
private void DrawActionMaps()
|
||||
{
|
||||
if (_target == null || !_target.IsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
object mapsObj = ActionMapsField?.GetValue(_target);
|
||||
if (!(mapsObj is Dictionary<InputContextId, InputActionMap> maps))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField("Action Maps", EditorStyles.boldLabel);
|
||||
|
||||
foreach (KeyValuePair<InputContextId, InputActionMap> pair in maps)
|
||||
{
|
||||
InputContextId contextId = pair.Key;
|
||||
InputActionMap map = pair.Value;
|
||||
|
||||
bool enabled = map?.enabled ?? false;
|
||||
bool isActive = contextId == InputContextId.Global || contextId == _target.CurrentContext;
|
||||
|
||||
Color previousColor = GUI.color;
|
||||
if (enabled)
|
||||
{
|
||||
GUI.color = isActive ? Color.green : Color.yellow;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.gray;
|
||||
}
|
||||
|
||||
if (!_mapFoldouts.ContainsKey(contextId))
|
||||
{
|
||||
_mapFoldouts[contextId] = false;
|
||||
}
|
||||
|
||||
_mapFoldouts[contextId] = EditorGUILayout.Foldout(_mapFoldouts[contextId], $"{contextId} [{StateLabel(enabled, isActive)}]", true);
|
||||
|
||||
GUI.color = previousColor;
|
||||
|
||||
if (_mapFoldouts[contextId] && map != null)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
foreach (InputAction action in map.actions)
|
||||
{
|
||||
DrawAction(action);
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawAction(InputAction action)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(action.name, GUILayout.Width(120));
|
||||
|
||||
if (action.bindings.Count > 0)
|
||||
{
|
||||
var parts = new System.Collections.Generic.List<string>(action.bindings.Count);
|
||||
foreach (InputBinding binding in action.bindings)
|
||||
{
|
||||
string path = string.IsNullOrEmpty(binding.overridePath) ? binding.path : binding.overridePath;
|
||||
bool hasOverride = !string.IsNullOrEmpty(binding.overridePath);
|
||||
string display = string.IsNullOrEmpty(path) ? "(none)" : path;
|
||||
if (hasOverride)
|
||||
{
|
||||
display += " *";
|
||||
}
|
||||
|
||||
parts.Add(display);
|
||||
}
|
||||
|
||||
bool anyOverride = false;
|
||||
foreach (InputBinding binding in action.bindings)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(binding.overridePath))
|
||||
{
|
||||
anyOverride = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GUIStyle style = anyOverride ? EditorStyles.boldLabel : EditorStyles.miniLabel;
|
||||
EditorGUILayout.LabelField(string.Join(" | ", parts), style);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("(no bindings)", EditorStyles.miniLabel);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private static string StateLabel(bool enabled, bool isActive)
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return "disabled";
|
||||
}
|
||||
|
||||
return isActive ? "active" : "enabled";
|
||||
}
|
||||
|
||||
private static InputModuleComponent FindInputModuleComponent()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
InputModuleComponent found = UnityEngine.Object.FindObjectOfType<InputModuleComponent>();
|
||||
if (found != null)
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0509216eba2f2b409f04dff46933b14
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "SepCore.InputModule.Editor",
|
||||
"rootNamespace": "SepCore.InputModule.Editor",
|
||||
"references": [
|
||||
"GUID:d54b9488b03814a44ab937f0aeb738b1",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||
"GUID:363c5eb08ff8e6a439b85e37b8c20d96",
|
||||
"GUID:436e23dbdc31e7d4fb5c3f804548b2df"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5f56cf3c36e431448e6e616bb5bf586
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user