14 #region Reflection cache
16 static Type TKeyboard => t_Keyboard ??= ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Keyboard");
17 static Type? t_Keyboard;
20 static Type TMouse => t_Mouse ??= ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Mouse");
24 static Type TGamepad => t_Gamepad ??= ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Gamepad");
25 static Type? t_Gamepad;
28 static Type TKey => t_Key ??= ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Key");
32 static PropertyInfo? p_btnIsPressed;
34 static PropertyInfo? p_btnWasPressed;
36 static PropertyInfo? p_btnWasReleased;
39 static object? CurrentKeyboard => p_kbCurrent?.GetValue(
null,
null);
40 static PropertyInfo? p_kbCurrent;
42 static PropertyInfo? p_kbIndexer;
45 static object? CurrentMouse => p_mouseCurrent?.GetValue(
null,
null);
46 static PropertyInfo? p_mouseCurrent;
49 static object? LeftMouseButton => p_leftButton?.GetValue(CurrentMouse,
null);
50 static PropertyInfo? p_leftButton;
53 static object? RightMouseButton => p_rightButton?.GetValue(CurrentMouse,
null);
54 static PropertyInfo? p_rightButton;
57 static object? MiddleMouseButton => p_middleButton?.GetValue(CurrentMouse,
null);
58 static PropertyInfo? p_middleButton;
61 static object? ForwardMouseButton => p_forwardButton?.GetValue(CurrentMouse,
null);
62 static PropertyInfo? p_forwardButton;
65 static object? BackMouseButton => p_backButton?.GetValue(CurrentMouse,
null);
66 static PropertyInfo? p_backButton;
69 static object? CurrentGamepad => p_gamepadCurrent?.GetValue(
null,
null);
70 static PropertyInfo? p_gamepadCurrent;
73 static object? ButtonGamepadWest => p_buttonWest?.GetValue(CurrentGamepad,
null);
74 static PropertyInfo? p_buttonWest;
77 static object? ButtonGamepadNorth => p_buttonNorth?.GetValue(CurrentGamepad,
null);
78 static PropertyInfo? p_buttonNorth;
81 static object? ButtonGamepadSouth => p_buttonSouth?.GetValue(CurrentGamepad,
null);
82 static PropertyInfo? p_buttonSouth;
85 static object? ButtonGamepadEast => p_buttonEast?.GetValue(CurrentGamepad,
null);
86 static PropertyInfo? p_buttonEast;
89 static object? StartButton => p_startButton?.GetValue(CurrentGamepad,
null);
90 static PropertyInfo? p_startButton;
93 static object? SelectButton => p_selectButton?.GetValue(CurrentGamepad,
null);
94 static PropertyInfo? p_selectButton;
97 static object? LeftStickButton => p_leftStickButton?.GetValue(CurrentGamepad,
null);
98 static PropertyInfo? p_leftStickButton;
101 static object? RightStickButton => p_rightStickButton?.GetValue(CurrentGamepad,
null);
102 static PropertyInfo? p_rightStickButton;
105 static object? Dpad => p_dpad?.GetValue(CurrentGamepad,
null);
106 static PropertyInfo? p_dpad;
109 static object? DpadUp => p_dpadUp?.GetValue(Dpad,
null);
110 static PropertyInfo? p_dpadUp;
113 static object? DpadDown => p_dpadDown?.GetValue(Dpad,
null);
114 static PropertyInfo? p_dpadDown;
117 static object? DpadLeft => p_dpadLeft?.GetValue(Dpad,
null);
118 static PropertyInfo? p_dpadLeft;
121 static object? DpadRight => p_dpadRight?.GetValue(Dpad,
null);
122 static PropertyInfo? p_dpadRight;
125 static object? LeftShoulder => p_leftShoulder?.GetValue(CurrentGamepad,
null);
126 static PropertyInfo? p_leftShoulder;
129 static object? RightShoulder => p_rightShoulder?.GetValue(CurrentGamepad,
null);
130 static PropertyInfo? p_rightShoulder;
133 static object? LeftStick => p_leftStick?.GetValue(CurrentGamepad,
null);
134 static PropertyInfo? p_leftStick;
137 static object? RightStick => p_rightStick?.GetValue(CurrentGamepad,
null);
138 static PropertyInfo? p_rightStick;
141 static object? LeftTrigger => p_leftTrigger?.GetValue(CurrentGamepad,
null);
142 static PropertyInfo? p_leftTrigger;
145 static object? RightTrigger => p_rightTrigger?.GetValue(CurrentGamepad,
null);
146 static PropertyInfo? p_rightTrigger;
149 static MethodInfo? m_ReadV2Control;
152 static object? MousePositionInfo => p_position?.GetValue(CurrentMouse,
null);
153 static PropertyInfo? p_position;
156 static object? MouseScrollInfo => p_scrollDelta?.GetValue(CurrentMouse,
null);
157 static PropertyInfo? p_scrollDelta;
160 internal static bool Initialized =
false;
162 internal static void Initialize()
167 p_kbCurrent = TKeyboard.GetProperty(
"current");
168 p_kbIndexer = TKeyboard.GetProperty(
"Item",
new[] {TKey} );
170 Type t_btnControl = ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Controls.ButtonControl");
171 p_btnIsPressed = t_btnControl.GetProperty(
"isPressed");
172 p_btnWasPressed = t_btnControl.GetProperty(
"wasPressedThisFrame");
173 p_btnWasReleased = t_btnControl.GetProperty(
"wasReleasedThisFrame");
175 p_mouseCurrent = TMouse.GetProperty(
"current");
176 p_leftButton = TMouse.GetProperty(
"leftButton");
177 p_rightButton = TMouse.GetProperty(
"rightButton");
178 p_middleButton = TMouse.GetProperty(
"middleButton");
179 p_backButton = TMouse.GetProperty(
"backButton");
180 p_forwardButton = TMouse.GetProperty(
"forwardButton");
181 p_scrollDelta = TMouse.GetProperty(
"scroll");
183 p_position = ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Pointer")
184 .GetProperty(
"position");
186 p_gamepadCurrent = TGamepad.GetProperty(
"current");
187 p_buttonWest = TGamepad.GetProperty(
"buttonWest");
188 p_buttonNorth = TGamepad.GetProperty(
"buttonNorth");
189 p_buttonSouth = TGamepad.GetProperty(
"buttonSouth");
190 p_buttonEast = TGamepad.GetProperty(
"buttonEast");
191 p_startButton = TGamepad.GetProperty(
"startButton");
192 p_selectButton = TGamepad.GetProperty(
"selectButton");
193 p_leftStickButton = TGamepad.GetProperty(
"leftStickButton");
194 p_rightStickButton = TGamepad.GetProperty(
"rightStickButton");
196 p_dpad = TGamepad.GetProperty(
"dpad");
198 Type t_dpad = ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.Controls.DpadControl");
200 p_dpadUp = t_dpad.GetProperty(
"up");
201 p_dpadDown = t_dpad.GetProperty(
"down");
202 p_dpadLeft = t_dpad.GetProperty(
"left");
203 p_dpadRight = t_dpad.GetProperty(
"right");
205 p_leftShoulder = TGamepad.GetProperty(
"leftShoulder");
206 p_rightShoulder = TGamepad.GetProperty(
"rightShoulder");
207 p_leftStick = TGamepad.GetProperty(
"leftStick");
208 p_rightStick = TGamepad.GetProperty(
"rightStick");
209 p_leftTrigger = TGamepad.GetProperty(
"leftTrigger");
210 p_rightTrigger = TGamepad.GetProperty(
"rightTrigger");
212 m_ReadV2Control = ReflectionUtility.GetTypeByName(
"UnityEngine.InputSystem.InputControl`1")
213 .MakeGenericType(typeof(Vector2))
214 .GetMethod(
"ReadValue");
219 #region KeyCode -> control helpers
220 private static Dictionary<KeyCode, object?> KeyCodeToKeyboardKeyCache =
new();
222 private static readonly Dictionary<string, string> keycodeToKeyFixes =
new()
224 {
"Control",
"Ctrl" },
225 {
"Return",
"Enter" },
226 {
"Alpha",
"Digit" },
227 {
"Keypad",
"Numpad" },
228 {
"Numlock",
"NumLock" },
229 {
"Print",
"PrintScreen" },
230 {
"BackQuote",
"Backquote" }
233 private enum KeyCodeDeviceType
241 private static bool IsJoystickKeyCode(KeyCode key)
243 return key >= KeyCode.JoystickButton0 && key <= KeyCode.JoystickButton19;
246 private static bool IsMouseKeyCode(KeyCode key)
248 return key >= KeyCode.Mouse0 && key <= KeyCode.Mouse6;
251 private static object? KeyCodeToKeyEnum(KeyCode key)
253 string s = key.ToString();
255 foreach (KeyValuePair<string, string> fix
in keycodeToKeyFixes)
257 if (s.Contains(fix.Key))
259 s = s.Replace(fix.Key, fix.Value);
266 return Enum.Parse(TKey, s);
274 private static object? KeyCodeToKeyboardControl(KeyCode key)
276 if (CurrentKeyboard ==
null)
279 if (KeyCodeToKeyboardKeyCache.TryGetValue(key, out
object? cached))
282 object? result =
null;
284 if (p_kbIndexer is not
null && CurrentKeyboard is not
null)
286 object? parsed = KeyCodeToKeyEnum(key);
288 if (parsed is not
null)
292 result = p_kbIndexer.GetValue(CurrentKeyboard, [parsed]);
301 KeyCodeToKeyboardKeyCache[key] = result;
305 private static object? KeyCodeToMouseControl(KeyCode key)
307 if (CurrentMouse ==
null)
312 KeyCode.Mouse0 => LeftMouseButton,
313 KeyCode.Mouse1 => RightMouseButton,
314 KeyCode.Mouse2 => MiddleMouseButton,
315 KeyCode.Mouse3 => BackMouseButton,
316 KeyCode.Mouse4 => ForwardMouseButton,
321 private static object? KeyCodeToGamepadControl(KeyCode key)
323 if (CurrentGamepad ==
null)
328 KeyCode.JoystickButton0 => ButtonGamepadSouth,
329 KeyCode.JoystickButton1 => ButtonGamepadEast,
330 KeyCode.JoystickButton2 => ButtonGamepadWest,
331 KeyCode.JoystickButton3 => ButtonGamepadNorth,
332 KeyCode.JoystickButton4 => LeftShoulder,
333 KeyCode.JoystickButton5 => RightShoulder,
334 KeyCode.JoystickButton6 => LeftTrigger,
335 KeyCode.JoystickButton7 => RightTrigger,
336 KeyCode.JoystickButton8 => SelectButton,
337 KeyCode.JoystickButton9 => StartButton,
338 KeyCode.JoystickButton10 => LeftStickButton,
339 KeyCode.JoystickButton11 => RightStickButton,
340 KeyCode.JoystickButton12 => DpadUp,
341 KeyCode.JoystickButton13 => DpadDown,
342 KeyCode.JoystickButton14 => DpadLeft,
343 KeyCode.JoystickButton15 => DpadRight,
348 private static KeyCodeDeviceType GetDeviceType(KeyCode key)
350 if (IsMouseKeyCode(key))
351 return KeyCodeDeviceType.Mouse;
353 if (IsJoystickKeyCode(key))
354 return KeyCodeDeviceType.Gamepad;
356 return KeyCodeDeviceType.Keyboard;
359 private static object? KeyCodeToControl(KeyCode key)
361 object? control =
null;
363 switch (GetDeviceType(key))
365 case KeyCodeDeviceType.Mouse:
366 control = KeyCodeToMouseControl(key);
369 case KeyCodeDeviceType.Gamepad:
370 control = KeyCodeToGamepadControl(key);
373 case KeyCodeDeviceType.Keyboard:
374 control = KeyCodeToKeyboardControl(key);
381 private static bool TryGetControlState(
object? control, PropertyInfo? stateProperty, out
bool state)
385 if (control is
null || stateProperty is
null)
390 object? value = stateProperty.GetValue(control,
null);
408 if (!Initialized || p_btnWasPressed is
null)
411 object? control = KeyCodeToControl(key);
412 return TryGetControlState(control, p_btnWasPressed, out
bool state) && state;
417 if (!Initialized || p_btnIsPressed is
null)
420 object? control = KeyCodeToControl(key);
421 return TryGetControlState(control, p_btnIsPressed, out
bool state) && state;
426 if (!Initialized || p_btnWasReleased is
null)
429 object? control = KeyCodeToControl(key);
430 return TryGetControlState(control, p_btnWasReleased, out
bool state) && state;
438 foreach (KeyCode key
in Enum.GetValues(typeof(KeyCode)))
440 object? control = KeyCodeToControl(key);
441 if (TryGetControlState(control, p_btnIsPressed, out
bool state) && state)