WKLib 0.2.3
A modding library for White Knuckle
Loading...
Searching...
No Matches
InputUtility.cs
Go to the documentation of this file.
1#nullable enable
2using System;
3using System.Collections.Generic;
4using System.Reflection;
5using UnityEngine;
7
9
10// https://github.com/yukieiji/UniverseLib/blob/main/src/Input/InputSystem.cs
11
12public static class InputUtility
13{
14 #region Reflection cache
15 // typeof(InputSystem.Keyboard)
16 static Type TKeyboard => t_Keyboard ??= ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.Keyboard");
17 static Type? t_Keyboard;
18
19 // typeof(InputSystem.Mouse)
20 static Type TMouse => t_Mouse ??= ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.Mouse");
21 static Type? t_Mouse;
22
23 // typeof(InputSystem.Gamepad)
24 static Type TGamepad => t_Gamepad ??= ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.Gamepad");
25 static Type? t_Gamepad;
26
27 // typeof (InputSystem.Key)
28 static Type TKey => t_Key ??= ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.Key");
29 static Type? t_Key;
30
31 // InputSystem.Controls.ButtonControl.isPressed
32 static PropertyInfo? p_btnIsPressed;
33 // InputSystem.Controls.ButtonControl.wasPressedThisFrame
34 static PropertyInfo? p_btnWasPressed;
35 // InputSystem.Controls.ButtonControl.wasReleasedThisFrame
36 static PropertyInfo? p_btnWasReleased;
37
38 // Keyboard.current
39 static object? CurrentKeyboard => p_kbCurrent?.GetValue(null, null);
40 static PropertyInfo? p_kbCurrent;
41 // Keyboard.this[Key]
42 static PropertyInfo? p_kbIndexer;
43
44 // Mouse.current
45 static object? CurrentMouse => p_mouseCurrent?.GetValue(null, null);
46 static PropertyInfo? p_mouseCurrent;
47
48 // Mouse.current.leftButton
49 static object? LeftMouseButton => p_leftButton?.GetValue(CurrentMouse, null);
50 static PropertyInfo? p_leftButton;
51
52 // Mouse.current.rightButton
53 static object? RightMouseButton => p_rightButton?.GetValue(CurrentMouse, null);
54 static PropertyInfo? p_rightButton;
55
56 // Mouse.current.middleButton
57 static object? MiddleMouseButton => p_middleButton?.GetValue(CurrentMouse, null);
58 static PropertyInfo? p_middleButton;
59
60 // Mouse.current.forwardButton
61 static object? ForwardMouseButton => p_forwardButton?.GetValue(CurrentMouse, null);
62 static PropertyInfo? p_forwardButton;
63
64 // Mouse.current.backButton
65 static object? BackMouseButton => p_backButton?.GetValue(CurrentMouse, null);
66 static PropertyInfo? p_backButton;
67
68 // Gamepad.current
69 static object? CurrentGamepad => p_gamepadCurrent?.GetValue(null, null);
70 static PropertyInfo? p_gamepadCurrent;
71
72 // Gamepad.current.buttonWest
73 static object? ButtonGamepadWest => p_buttonWest?.GetValue(CurrentGamepad, null);
74 static PropertyInfo? p_buttonWest;
75
76 // Gamepad.current.buttonNorth
77 static object? ButtonGamepadNorth => p_buttonNorth?.GetValue(CurrentGamepad, null);
78 static PropertyInfo? p_buttonNorth;
79
80 // Gamepad.current.buttonSouth
81 static object? ButtonGamepadSouth => p_buttonSouth?.GetValue(CurrentGamepad, null);
82 static PropertyInfo? p_buttonSouth;
83
84 // Gamepad.current.buttonEast
85 static object? ButtonGamepadEast => p_buttonEast?.GetValue(CurrentGamepad, null);
86 static PropertyInfo? p_buttonEast;
87
88 // Gamepad.current.startButton
89 static object? StartButton => p_startButton?.GetValue(CurrentGamepad, null);
90 static PropertyInfo? p_startButton;
91
92 // Gamepad.current.selectButton
93 static object? SelectButton => p_selectButton?.GetValue(CurrentGamepad, null);
94 static PropertyInfo? p_selectButton;
95
96 // Gamepad.current.leftStickButton
97 static object? LeftStickButton => p_leftStickButton?.GetValue(CurrentGamepad, null);
98 static PropertyInfo? p_leftStickButton;
99
100 // Gamepad.current.rightStickButton
101 static object? RightStickButton => p_rightStickButton?.GetValue(CurrentGamepad, null);
102 static PropertyInfo? p_rightStickButton;
103
104 // Gamepad.current.dpad
105 static object? Dpad => p_dpad?.GetValue(CurrentGamepad, null);
106 static PropertyInfo? p_dpad;
107
108 // Gamepad.current.dpad.up
109 static object? DpadUp => p_dpadUp?.GetValue(Dpad, null);
110 static PropertyInfo? p_dpadUp;
111
112 // Gamepad.current.dpad.down
113 static object? DpadDown => p_dpadDown?.GetValue(Dpad, null);
114 static PropertyInfo? p_dpadDown;
115
116 // Gamepad.current.dpad.left
117 static object? DpadLeft => p_dpadLeft?.GetValue(Dpad, null);
118 static PropertyInfo? p_dpadLeft;
119
120 // Gamepad.current.dpad.right
121 static object? DpadRight => p_dpadRight?.GetValue(Dpad, null);
122 static PropertyInfo? p_dpadRight;
123
124 // Gamepad.current.leftShoulder
125 static object? LeftShoulder => p_leftShoulder?.GetValue(CurrentGamepad, null);
126 static PropertyInfo? p_leftShoulder;
127
128 // Gamepad.current.rightShoulder
129 static object? RightShoulder => p_rightShoulder?.GetValue(CurrentGamepad, null);
130 static PropertyInfo? p_rightShoulder;
131
132 // Gamepad.current.leftStick
133 static object? LeftStick => p_leftStick?.GetValue(CurrentGamepad, null);
134 static PropertyInfo? p_leftStick;
135
136 // Gamepad.current.rightStick
137 static object? RightStick => p_rightStick?.GetValue(CurrentGamepad, null);
138 static PropertyInfo? p_rightStick;
139
140 // Gamepad.current.leftTrigger
141 static object? LeftTrigger => p_leftTrigger?.GetValue(CurrentGamepad, null);
142 static PropertyInfo? p_leftTrigger;
143
144 // Gamepad.current.rightTrigger
145 static object? RightTrigger => p_rightTrigger?.GetValue(CurrentGamepad, null);
146 static PropertyInfo? p_rightTrigger;
147
148 // InputSystem.InputControl<Vector2>.ReadValue()
149 static MethodInfo? m_ReadV2Control;
150
151 // Mouse.current.position
152 static object? MousePositionInfo => p_position?.GetValue(CurrentMouse, null);
153 static PropertyInfo? p_position;
154
155 // Mouse.current.scroll
156 static object? MouseScrollInfo => p_scrollDelta?.GetValue(CurrentMouse, null);
157 static PropertyInfo? p_scrollDelta;
158 #endregion
159
160 internal static bool Initialized = false;
161
162 internal static void Initialize()
163 {
164 if (Initialized)
165 return;
166
167 p_kbCurrent = TKeyboard.GetProperty("current");
168 p_kbIndexer = TKeyboard.GetProperty("Item", new[] {TKey} );
169
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");
174
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");
182
183 p_position = ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.Pointer")
184 .GetProperty("position");
185
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");
195
196 p_dpad = TGamepad.GetProperty("dpad");
197
198 Type t_dpad = ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.Controls.DpadControl");
199
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");
204
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");
211
212 m_ReadV2Control = ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.InputControl`1")
213 .MakeGenericType(typeof(Vector2))
214 .GetMethod("ReadValue");
215
216 Initialized = true;
217 }
218
219 #region KeyCode -> control helpers
220 private static Dictionary<KeyCode, object?> KeyCodeToKeyboardKeyCache = new();
221
222 private static readonly Dictionary<string, string> keycodeToKeyFixes = new()
223 {
224 { "Control", "Ctrl" },
225 { "Return", "Enter" },
226 { "Alpha", "Digit" },
227 { "Keypad", "Numpad" },
228 { "Numlock", "NumLock" },
229 { "Print", "PrintScreen" },
230 { "BackQuote", "Backquote" }
231 };
232
233 private enum KeyCodeDeviceType
234 {
235 None,
236 Keyboard,
237 Mouse,
238 Gamepad
239 }
240
241 private static bool IsJoystickKeyCode(KeyCode key)
242 {
243 return key >= KeyCode.JoystickButton0 && key <= KeyCode.JoystickButton19;
244 }
245
246 private static bool IsMouseKeyCode(KeyCode key)
247 {
248 return key >= KeyCode.Mouse0 && key <= KeyCode.Mouse6;
249 }
250
251 private static object? KeyCodeToKeyEnum(KeyCode key)
252 {
253 string s = key.ToString();
254
255 foreach (KeyValuePair<string, string> fix in keycodeToKeyFixes)
256 {
257 if (s.Contains(fix.Key))
258 {
259 s = s.Replace(fix.Key, fix.Value);
260 break;
261 }
262 }
263
264 try
265 {
266 return Enum.Parse(TKey, s);
267 }
268 catch
269 {
270 return null;
271 }
272 }
273
274 private static object? KeyCodeToKeyboardControl(KeyCode key)
275 {
276 if (CurrentKeyboard == null)
277 return null;
278
279 if (KeyCodeToKeyboardKeyCache.TryGetValue(key, out object? cached))
280 return cached;
281
282 object? result = null;
283
284 if (p_kbIndexer is not null && CurrentKeyboard is not null)
285 {
286 object? parsed = KeyCodeToKeyEnum(key);
287
288 if (parsed is not null)
289 {
290 try
291 {
292 result = p_kbIndexer.GetValue(CurrentKeyboard, [parsed]);
293 }
294 catch
295 {
296 result = null;
297 }
298 }
299 }
300
301 KeyCodeToKeyboardKeyCache[key] = result;
302 return result;
303 }
304
305 private static object? KeyCodeToMouseControl(KeyCode key)
306 {
307 if (CurrentMouse == null)
308 return null;
309
310 return key switch
311 {
312 KeyCode.Mouse0 => LeftMouseButton,
313 KeyCode.Mouse1 => RightMouseButton,
314 KeyCode.Mouse2 => MiddleMouseButton,
315 KeyCode.Mouse3 => BackMouseButton,
316 KeyCode.Mouse4 => ForwardMouseButton,
317 _ => null
318 };
319 }
320
321 private static object? KeyCodeToGamepadControl(KeyCode key)
322 {
323 if (CurrentGamepad == null)
324 return null;
325
326 return key switch
327 {
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,
344 _ => null
345 };
346 }
347
348 private static KeyCodeDeviceType GetDeviceType(KeyCode key)
349 {
350 if (IsMouseKeyCode(key))
351 return KeyCodeDeviceType.Mouse;
352
353 if (IsJoystickKeyCode(key))
354 return KeyCodeDeviceType.Gamepad;
355
356 return KeyCodeDeviceType.Keyboard;
357 }
358
359 private static object? KeyCodeToControl(KeyCode key)
360 {
361 object? control = null;
362
363 switch (GetDeviceType(key))
364 {
365 case KeyCodeDeviceType.Mouse:
366 control = KeyCodeToMouseControl(key);
367 break;
368
369 case KeyCodeDeviceType.Gamepad:
370 control = KeyCodeToGamepadControl(key);
371 break;
372
373 case KeyCodeDeviceType.Keyboard:
374 control = KeyCodeToKeyboardControl(key);
375 break;
376 }
377
378 return control;
379 }
380
381 private static bool TryGetControlState(object? control, PropertyInfo? stateProperty, out bool state)
382 {
383 state = false;
384
385 if (control is null || stateProperty is null)
386 return false;
387
388 try
389 {
390 object? value = stateProperty.GetValue(control, null);
391 if (value is bool b)
392 {
393 state = b;
394 return true;
395 }
396 }
397 catch
398 {
399 return false;
400 }
401
402 return false;
403 }
404 #endregion
405
406 public static bool GetKeyDown(KeyCode key)
407 {
408 if (!Initialized || p_btnWasPressed is null)
409 return false;
410
411 object? control = KeyCodeToControl(key);
412 return TryGetControlState(control, p_btnWasPressed, out bool state) && state;
413 }
414
415 public static bool GetKey(KeyCode key)
416 {
417 if (!Initialized || p_btnIsPressed is null)
418 return false;
419
420 object? control = KeyCodeToControl(key);
421 return TryGetControlState(control, p_btnIsPressed, out bool state) && state;
422 }
423
424 public static bool GetKeyUp(KeyCode key)
425 {
426 if (!Initialized || p_btnWasReleased is null)
427 return false;
428
429 object? control = KeyCodeToControl(key);
430 return TryGetControlState(control, p_btnWasReleased, out bool state) && state;
431 }
432
433 public static KeyCode? GetFirstActiveKey()
434 {
435 if (!Initialized)
436 return null;
437
438 foreach (KeyCode key in Enum.GetValues(typeof(KeyCode)))
439 {
440 object? control = KeyCodeToControl(key);
441 if (TryGetControlState(control, p_btnIsPressed, out bool state) && state)
442 return key;
443 }
444
445 return null;
446 }
447}
static bool GetKeyUp(KeyCode key)
static bool GetKeyDown(KeyCode key)
static bool GetKey(KeyCode key)
static ? KeyCode GetFirstActiveKey()