Make UnityInput and KeyboardShortcut available in IL2CPP (#998)

This commit is contained in:
ManlyMarco authored and GitHub committed 2026-06-21 12:22:08 +02:00
1 parent 4a879f582c
commit 4aab2920fc
8 files changed
+1153 -15

No files matched your search

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>BepInEx support library for Il2Cpp games</Description>
<TargetFramework>net6.0</TargetFramework>
@@ -24,6 +24,20 @@
<PackageReference Include="MonoMod.RuntimeDetour" Version="22.7.31.1"/>
<PackageReference Include="Samboy063.Cpp2IL.Core" Version="2022.1.0-development.1452"/>
</ItemGroup>
<ItemGroup>
<Reference Include="Unity.InputSystem">
<HintPath>lib\Unity.InputSystem.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>lib\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>lib\UnityEngine.InputLegacyModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- CopyLocalLockFileAssemblies causes to also output shared assemblies: https://github.com/NuGet/Home/issues/4837#issuecomment-354536302 -->
<!-- Since all core assemblies usually follow naming of System.*, we just delete them for now -->
@@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx.Configuration;
using BepInEx.Logging;
using UnityEngine;
using Logger = BepInEx.Logging.Logger;
namespace BepInEx.Unity.IL2CPP.Configuration;
/// <summary>
/// A keyboard shortcut that can be used in Update method to check if user presses a key combo. The shortcut is only
/// triggered when the user presses the exact combination. For example, <c>F + LeftCtrl</c> will trigger only if user
/// presses and holds only LeftCtrl, and then presses F. If any other keys are pressed, the shortcut will not trigger.
/// Can be used as a value of a setting in <see cref="ConfigFile.Bind{T}(ConfigDefinition,T,ConfigDescription)" />
/// to allow user to change this shortcut and have the changes saved.
/// How to use: Use <see cref="IsDown" /> in this class instead of <see cref="Input.GetKeyDown(KeyCode)" /> in the
/// Update loop.
/// </summary>
public struct KeyboardShortcut
{
static KeyboardShortcut()
{
TomlTypeConverter.AddConverter(
typeof(KeyboardShortcut),
new TypeConverter
{
ConvertToString = (o, type) => ((KeyboardShortcut) o).Serialize(),
ConvertToObject = (s, type) => Deserialize(s)
});
}
/// <summary>
/// Shortcut that never triggers.
/// </summary>
public static readonly KeyboardShortcut Empty = new();
// Don't block hotkeys if mouse is being pressed, e.g. when shooting and trying to strafe
private static KeyCode[] modifierBlockKeyCodes;
private readonly KeyCode[] _allKeys;
/// <summary>
/// Create a new keyboard shortcut.
/// </summary>
/// <param name="mainKey">Main key to press</param>
/// <param name="modifiers">Keys that should be held down before main key is registered</param>
public KeyboardShortcut(KeyCode mainKey, params KeyCode[] modifiers) : this(new[] { mainKey }.Concat(modifiers)
.ToArray())
{
if (mainKey == KeyCode.None && modifiers.Any())
throw new
ArgumentException($"Can't set {nameof(mainKey)} to KeyCode.None if there are any {nameof(modifiers)}");
}
private KeyboardShortcut(KeyCode[] keys)
{
_allKeys = SanitizeKeys(keys);
}
private static KeyCode[] SanitizeKeys(params KeyCode[] keys)
{
if (keys.Length == 0 || keys[0] == KeyCode.None)
return new[] { KeyCode.None };
return new[] { keys[0] }.Concat(keys.Skip(1).Distinct().Where(x => x != keys[0]).OrderBy(x => (int) x))
.ToArray();
}
/// <summary>
/// Main key of the key combination. It has to be pressed / let go last for the combination to be triggered.
/// If the combination is empty, <see cref="KeyCode.None" /> is returned.
/// </summary>
public KeyCode MainKey => _allKeys != null && _allKeys.Length > 0 ? _allKeys[0] : KeyCode.None;
/// <summary>
/// Modifiers of the key combination, if any.
/// </summary>
public IEnumerable<KeyCode> Modifiers => _allKeys?.Skip(1) ?? Enumerable.Empty<KeyCode>();
/// <summary>
/// Attempt to deserialize key combination from the string.
/// </summary>
public static KeyboardShortcut Deserialize(string str)
{
try
{
var parts = str.Split(new[] { ' ', '+', ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => (KeyCode) Enum.Parse(typeof(KeyCode), x)).ToArray();
return new KeyboardShortcut(parts);
}
catch (SystemException ex)
{
Logger.Log(LogLevel.Error, "Failed to read keybind from settings: " + ex.Message);
return Empty;
}
}
/// <summary>
/// Serialize the key combination into a user readable string.
/// </summary>
public string Serialize()
{
if (_allKeys == null) return string.Empty;
return string.Join(" + ", _allKeys.Select(x => x.ToString()).ToArray());
}
/// <summary>
/// Check if the main key was just pressed (Input.GetKeyDown), and specified modifier keys are all pressed
/// </summary>
public bool IsDown()
{
var mainKey = MainKey;
if (mainKey == KeyCode.None) return false;
return UnityInput.Current.GetKeyDown(mainKey) && ModifierKeyTest();
}
/// <summary>
/// Check if the main key is currently held down (Input.GetKey), and specified modifier keys are all pressed
/// </summary>
public bool IsPressed()
{
var mainKey = MainKey;
if (mainKey == KeyCode.None) return false;
return UnityInput.Current.GetKey(mainKey) && ModifierKeyTest();
}
/// <summary>
/// Check if the main key was just lifted (Input.GetKeyUp), and specified modifier keys are all pressed.
/// </summary>
public bool IsUp()
{
var mainKey = MainKey;
if (mainKey == KeyCode.None) return false;
return UnityInput.Current.GetKeyUp(mainKey) && ModifierKeyTest();
}
private bool ModifierKeyTest()
{
var allKeys = _allKeys;
var mainKey = MainKey;
var allModifiersPressed = allKeys.All(c => c == mainKey || UnityInput.Current.GetKey(c));
if (!allModifiersPressed) return false;
// Lazy init to make sure the game is initialized, and we're in main thread before calling UnityInput.Current
modifierBlockKeyCodes ??= UnityInput.Current.SupportedKeyCodes.Except([KeyCode.Mouse0, KeyCode.Mouse1,
KeyCode.Mouse2, KeyCode.Mouse3, KeyCode.Mouse4, KeyCode.Mouse5, KeyCode.Mouse6, KeyCode.None
]).ToArray();
bool noOtherModifiersPressed = modifierBlockKeyCodes.All(c => !UnityInput.Current.GetKey(c) || allKeys.Contains(c));
return noOtherModifiersPressed;
}
/// <inheritdoc />
public override string ToString()
{
if (MainKey == KeyCode.None) return "Not set";
return string.Join(" + ", _allKeys.Select(c => c.ToString()).ToArray());
}
/// <inheritdoc />
public override bool Equals(object obj) =>
obj is KeyboardShortcut shortcut && MainKey == shortcut.MainKey &&
Modifiers.SequenceEqual(shortcut.Modifiers);
/// <inheritdoc />
public override int GetHashCode()
{
if (MainKey == KeyCode.None) return 0;
return _allKeys.Aggregate(_allKeys.Length, (current, item) => unchecked(current * 31 + (int) item));
}
}
@@ -1,5 +1,8 @@
namespace BepInEx.Unity.IL2CPP.UnityEngine;
using System;
namespace BepInEx.Unity.IL2CPP.UnityEngine;
[Obsolete("Use UnityInput instead")]
public enum KeyCode
{
None,
@@ -330,6 +333,7 @@ public enum KeyCode
Joystick8Button19
}
[Obsolete("Use UnityInput instead")]
public static class Input
{
private static readonly GetKeyIntDelegate GetKeyInt_Value
@@ -0,0 +1,898 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using BepInEx.Logging;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
// ReSharper disable InconsistentNaming
namespace BepInEx
{
/// <summary>
/// Abstraction layer over Unity's input systems for use in universal plugins that need to use hotkeys.
/// It can use either Input or Unity.InputSystem, depending on what's available. Input is preferred.
/// WARNING: Use only inside of Unity's main thread!
/// </summary>
public class UnityInput
{
private static IInputSystem current;
/// <summary>
/// Best currently supported input system.
/// </summary>
public static IInputSystem Current
{
get
{
if (current == null)
{
try
{
try
{
current = new LegacyInputSystem();
BepInEx.Logging.Logger.Log(LogLevel.Debug, "[UnityInput] Using LegacyInputSystem");
}
catch
{
var newInputSystem = new NewInputSystem();
current = newInputSystem;
BepInEx.Logging.Logger.Log(LogLevel.Debug, "[UnityInput] Using NewInputSystem");
}
}
catch (Exception ex)
{
current = new NullInputSystem();
BepInEx.Logging.Logger.Log(LogLevel.Warning, "[UnityInput] Failed to detect available input systems - " + ex);
}
}
return current;
}
}
/// <summary>
/// True if the Input class is not disabled.
/// </summary>
public bool LegacyInputSystemAvailable => Current is LegacyInputSystem;
}
/// <summary>
/// Generic input system interface. Just barely good enough for hotkeys.
/// </summary>
public interface IInputSystem
{
// No easy way to use these with the new input system
//bool GetButton(string buttonName);
//bool GetButtonDown(string buttonName);
//bool GetButtonUp(string buttonName);
/// <inheritdoc cref="Input.GetKey(string)"/>
bool GetKey(string name);
/// <inheritdoc cref="Input.GetKey(KeyCode)"/>
bool GetKey(KeyCode key);
/// <inheritdoc cref="Input.GetKeyDown(string)"/>
bool GetKeyDown(string name);
/// <inheritdoc cref="Input.GetKeyDown(KeyCode)"/>
bool GetKeyDown(KeyCode key);
/// <inheritdoc cref="Input.GetKeyUp(string)"/>
bool GetKeyUp(string name);
/// <inheritdoc cref="Input.GetKeyUp(KeyCode)"/>
bool GetKeyUp(KeyCode key);
/// <inheritdoc cref="Input.GetMouseButton(int)"/>
bool GetMouseButton(int button);
/// <inheritdoc cref="Input.GetMouseButtonDown(int)"/>
bool GetMouseButtonDown(int button);
/// <inheritdoc cref="Input.GetMouseButtonUp(int)"/>
bool GetMouseButtonUp(int button);
/// <inheritdoc cref="Input.ResetInputAxes()"/>
void ResetInputAxes();
/// <inheritdoc cref="Input.mousePosition"/>
Vector3 mousePosition { get; }
/// <inheritdoc cref="Input.mouseScrollDelta"/>
Vector2 mouseScrollDelta { get; }
/// <inheritdoc cref="Input.mousePresent"/>
bool mousePresent { get; }
/// <inheritdoc cref="Input.anyKey"/>
bool anyKey { get; }
/// <inheritdoc cref="Input.anyKeyDown"/>
bool anyKeyDown { get; }
/// <summary>
/// All KeyCodes supported by the current input system.
/// </summary>
IEnumerable<KeyCode> SupportedKeyCodes { get; }
}
internal class NullInputSystem : IInputSystem
{
public bool GetKey(string name) => false;
public bool GetKey(KeyCode key) => false;
public bool GetKeyDown(string name) => false;
public bool GetKeyDown(KeyCode key) => false;
public bool GetKeyUp(string name) => false;
public bool GetKeyUp(KeyCode key) => false;
public bool GetMouseButton(int button) => false;
public bool GetMouseButtonDown(int button) => false;
public bool GetMouseButtonUp(int button) => false;
public void ResetInputAxes() { }
public Vector3 mousePosition => Vector3.zero;
public Vector2 mouseScrollDelta => Vector2.zero;
public bool mousePresent => false;
public bool anyKey => false;
public bool anyKeyDown => false;
public IEnumerable<KeyCode> SupportedKeyCodes { get; } = Enumerable.Empty<KeyCode>();
}
internal class NewInputSystem : IInputSystem
{
[MethodImpl(MethodImplOptions.NoInlining)]
public NewInputSystem() => GetKeyDown(KeyCode.A);
public bool GetKey(string name) => GetControl(name)?.isPressed ?? false;
public bool GetKey(KeyCode key) => GetControl(key)?.isPressed ?? false;
public bool GetKeyDown(string name) => GetControl(name)?.wasPressedThisFrame ?? false;
public bool GetKeyDown(KeyCode key) => GetControl(key)?.wasPressedThisFrame ?? false;
public bool GetKeyUp(string name) => GetControl(name)?.wasReleasedThisFrame ?? false;
public bool GetKeyUp(KeyCode key) => GetControl(key)?.wasReleasedThisFrame ?? false;
public bool GetMouseButton(int button) => GetControl(KeyCode.Mouse0 + button)?.isPressed ?? false;
public bool GetMouseButtonDown(int button) => GetControl(KeyCode.Mouse0 + button)?.wasPressedThisFrame ?? false;
public bool GetMouseButtonUp(int button) => GetControl(KeyCode.Mouse0 + button)?.wasReleasedThisFrame ?? false;
public void ResetInputAxes() { /*Not supported*/ }
public Vector3 mousePosition => Mouse.current.position.ReadValue();
public Vector2 mouseScrollDelta => Mouse.current.scroll.ReadValue();
public bool mousePresent => Mouse.current.enabled;
public bool anyKey
{
get
{
if (Keyboard.current.anyKey.isPressed)
return true;
var current = Mouse.current;
return current.leftButton.isPressed ||
current.rightButton.isPressed ||
current.forwardButton.isPressed ||
current.backButton.isPressed ||
current.middleButton.isPressed;
}
}
public bool anyKeyDown
{
get
{
if (Keyboard.current.anyKey.wasPressedThisFrame)
return true;
var current = Mouse.current;
return current.leftButton.wasPressedThisFrame ||
current.rightButton.wasPressedThisFrame ||
current.forwardButton.wasPressedThisFrame ||
current.backButton.wasPressedThisFrame ||
current.middleButton.wasPressedThisFrame;
}
}
public IEnumerable<KeyCode> SupportedKeyCodes { get; } = Enum.GetValues(typeof(KeyCode)).Cast<KeyCode>().Where(x => GetControl(x, true) != null).ToList();
private static ButtonControl GetControl(string name) => GetControl((KeyCode)Enum.Parse(typeof(KeyCode), name, true));
private static ButtonControl GetControl(KeyCode key, bool silent = false)
{
switch (key)
{
case KeyCode.None:
break;
case KeyCode.Backspace:
return Keyboard.current.backspaceKey;
case KeyCode.Delete:
return Keyboard.current.deleteKey;
case KeyCode.Tab:
return Keyboard.current.tabKey;
case KeyCode.Clear:
break;
case KeyCode.Return:
return Keyboard.current.enterKey;
case KeyCode.Pause:
return Keyboard.current.pauseKey;
case KeyCode.Escape:
return Keyboard.current.escapeKey;
case KeyCode.Space:
return Keyboard.current.spaceKey;
case KeyCode.Keypad0:
return Keyboard.current.numpad0Key;
case KeyCode.Keypad1:
return Keyboard.current.numpad1Key;
case KeyCode.Keypad2:
return Keyboard.current.numpad2Key;
case KeyCode.Keypad3:
return Keyboard.current.numpad3Key;
case KeyCode.Keypad4:
return Keyboard.current.numpad4Key;
case KeyCode.Keypad5:
return Keyboard.current.numpad5Key;
case KeyCode.Keypad6:
return Keyboard.current.numpad6Key;
case KeyCode.Keypad7:
return Keyboard.current.numpad7Key;
case KeyCode.Keypad8:
return Keyboard.current.numpad8Key;
case KeyCode.Keypad9:
return Keyboard.current.numpad9Key;
case KeyCode.KeypadPeriod:
return Keyboard.current.numpadPeriodKey;
case KeyCode.KeypadDivide:
return Keyboard.current.numpadDivideKey;
case KeyCode.KeypadMultiply:
return Keyboard.current.numpadMultiplyKey;
case KeyCode.KeypadMinus:
return Keyboard.current.numpadMinusKey;
case KeyCode.KeypadPlus:
return Keyboard.current.numpadPlusKey;
case KeyCode.KeypadEnter:
return Keyboard.current.numpadEnterKey;
case KeyCode.KeypadEquals:
return Keyboard.current.numpadEqualsKey;
case KeyCode.UpArrow:
return Keyboard.current.upArrowKey;
case KeyCode.DownArrow:
return Keyboard.current.downArrowKey;
case KeyCode.RightArrow:
return Keyboard.current.rightArrowKey;
case KeyCode.LeftArrow:
return Keyboard.current.leftArrowKey;
case KeyCode.Insert:
return Keyboard.current.insertKey;
case KeyCode.Home:
return Keyboard.current.homeKey;
case KeyCode.End:
return Keyboard.current.endKey;
case KeyCode.PageUp:
return Keyboard.current.pageUpKey;
case KeyCode.PageDown:
return Keyboard.current.pageDownKey;
case KeyCode.F1:
return Keyboard.current.f1Key;
case KeyCode.F2:
return Keyboard.current.f2Key;
case KeyCode.F3:
return Keyboard.current.f3Key;
case KeyCode.F4:
return Keyboard.current.f4Key;
case KeyCode.F5:
return Keyboard.current.f5Key;
case KeyCode.F6:
return Keyboard.current.f6Key;
case KeyCode.F7:
return Keyboard.current.f7Key;
case KeyCode.F8:
return Keyboard.current.f8Key;
case KeyCode.F9:
return Keyboard.current.f9Key;
case KeyCode.F10:
return Keyboard.current.f10Key;
case KeyCode.F11:
return Keyboard.current.f11Key;
case KeyCode.F12:
return Keyboard.current.f12Key;
case KeyCode.F13:
break;
case KeyCode.F14:
break;
case KeyCode.F15:
break;
case KeyCode.Alpha0:
return Keyboard.current.digit0Key;
case KeyCode.Alpha1:
return Keyboard.current.digit1Key;
case KeyCode.Alpha2:
return Keyboard.current.digit2Key;
case KeyCode.Alpha3:
return Keyboard.current.digit3Key;
case KeyCode.Alpha4:
return Keyboard.current.digit4Key;
case KeyCode.Alpha5:
return Keyboard.current.digit5Key;
case KeyCode.Alpha6:
return Keyboard.current.digit6Key;
case KeyCode.Alpha7:
return Keyboard.current.digit7Key;
case KeyCode.Alpha8:
return Keyboard.current.digit8Key;
case KeyCode.Alpha9:
return Keyboard.current.digit9Key;
case KeyCode.Exclaim:
break;
case KeyCode.DoubleQuote:
break;
case KeyCode.Hash:
break;
case KeyCode.Dollar:
break;
case KeyCode.Ampersand:
break;
case KeyCode.Quote:
return Keyboard.current.quoteKey;
case KeyCode.LeftParen:
break;
case KeyCode.RightParen:
break;
case KeyCode.Asterisk:
break;
case KeyCode.Plus:
return Keyboard.current.numpadPlusKey;
case KeyCode.Comma:
return Keyboard.current.commaKey;
case KeyCode.Minus:
return Keyboard.current.minusKey;
case KeyCode.Period:
return Keyboard.current.periodKey;
case KeyCode.Slash:
return Keyboard.current.slashKey;
case KeyCode.Colon:
break;
case KeyCode.Semicolon:
return Keyboard.current.semicolonKey;
case KeyCode.Less:
break;
case KeyCode.Equals:
return Keyboard.current.equalsKey;
case KeyCode.Greater:
break;
case KeyCode.Question:
break;
case KeyCode.At:
break;
case KeyCode.LeftBracket:
return Keyboard.current.leftBracketKey;
case KeyCode.Backslash:
return Keyboard.current.backslashKey;
case KeyCode.RightBracket:
return Keyboard.current.rightBracketKey;
case KeyCode.Caret:
break;
case KeyCode.Underscore:
break;
case KeyCode.BackQuote:
return Keyboard.current.backquoteKey;
case KeyCode.A:
return Keyboard.current.aKey;
case KeyCode.B:
return Keyboard.current.bKey;
case KeyCode.C:
return Keyboard.current.cKey;
case KeyCode.D:
return Keyboard.current.dKey;
case KeyCode.E:
return Keyboard.current.eKey;
case KeyCode.F:
return Keyboard.current.fKey;
case KeyCode.G:
return Keyboard.current.gKey;
case KeyCode.H:
return Keyboard.current.hKey;
case KeyCode.I:
return Keyboard.current.iKey;
case KeyCode.J:
return Keyboard.current.jKey;
case KeyCode.K:
return Keyboard.current.kKey;
case KeyCode.L:
return Keyboard.current.lKey;
case KeyCode.M:
return Keyboard.current.mKey;
case KeyCode.N:
return Keyboard.current.nKey;
case KeyCode.O:
return Keyboard.current.oKey;
case KeyCode.P:
return Keyboard.current.pKey;
case KeyCode.Q:
return Keyboard.current.qKey;
case KeyCode.R:
return Keyboard.current.rKey;
case KeyCode.S:
return Keyboard.current.sKey;
case KeyCode.T:
return Keyboard.current.tKey;
case KeyCode.U:
return Keyboard.current.uKey;
case KeyCode.V:
return Keyboard.current.vKey;
case KeyCode.W:
return Keyboard.current.wKey;
case KeyCode.X:
return Keyboard.current.xKey;
case KeyCode.Y:
return Keyboard.current.yKey;
case KeyCode.Z:
return Keyboard.current.zKey;
case KeyCode.Numlock:
return Keyboard.current.numLockKey;
case KeyCode.CapsLock:
return Keyboard.current.capsLockKey;
case KeyCode.ScrollLock:
return Keyboard.current.scrollLockKey;
case KeyCode.RightShift:
return Keyboard.current.rightShiftKey;
case KeyCode.LeftShift:
return Keyboard.current.leftShiftKey;
case KeyCode.RightControl:
return Keyboard.current.rightCtrlKey;
case KeyCode.LeftControl:
return Keyboard.current.leftCtrlKey;
case KeyCode.RightAlt:
return Keyboard.current.rightAltKey;
case KeyCode.LeftAlt:
return Keyboard.current.leftAltKey;
case KeyCode.LeftCommand:
return Keyboard.current.leftCommandKey;
case KeyCode.LeftWindows:
return Keyboard.current.leftWindowsKey;
case KeyCode.RightCommand:
return Keyboard.current.rightCommandKey;
case KeyCode.RightWindows:
return Keyboard.current.rightWindowsKey;
case KeyCode.AltGr:
break;
case KeyCode.Help:
break;
case KeyCode.Print:
return Keyboard.current.printScreenKey;
case KeyCode.SysReq:
break;
case KeyCode.Break:
break;
case KeyCode.Menu:
return Keyboard.current.contextMenuKey;
case KeyCode.Mouse0:
return Mouse.current.leftButton;
case KeyCode.Mouse1:
return Mouse.current.rightButton;
case KeyCode.Mouse2:
return Mouse.current.middleButton;
case KeyCode.Mouse3:
return Mouse.current.backButton;
case KeyCode.Mouse4:
return Mouse.current.forwardButton;
case KeyCode.Mouse5:
break;
case KeyCode.Mouse6:
break;
case KeyCode.JoystickButton0:
break;
case KeyCode.JoystickButton1:
break;
case KeyCode.JoystickButton2:
break;
case KeyCode.JoystickButton3:
break;
case KeyCode.JoystickButton4:
break;
case KeyCode.JoystickButton5:
break;
case KeyCode.JoystickButton6:
break;
case KeyCode.JoystickButton7:
break;
case KeyCode.JoystickButton8:
break;
case KeyCode.JoystickButton9:
break;
case KeyCode.JoystickButton10:
break;
case KeyCode.JoystickButton11:
break;
case KeyCode.JoystickButton12:
break;
case KeyCode.JoystickButton13:
break;
case KeyCode.JoystickButton14:
break;
case KeyCode.JoystickButton15:
break;
case KeyCode.JoystickButton16:
break;
case KeyCode.JoystickButton17:
break;
case KeyCode.JoystickButton18:
break;
case KeyCode.JoystickButton19:
break;
case KeyCode.Joystick1Button0:
break;
case KeyCode.Joystick1Button1:
break;
case KeyCode.Joystick1Button2:
break;
case KeyCode.Joystick1Button3:
break;
case KeyCode.Joystick1Button4:
break;
case KeyCode.Joystick1Button5:
break;
case KeyCode.Joystick1Button6:
break;
case KeyCode.Joystick1Button7:
break;
case KeyCode.Joystick1Button8:
break;
case KeyCode.Joystick1Button9:
break;
case KeyCode.Joystick1Button10:
break;
case KeyCode.Joystick1Button11:
break;
case KeyCode.Joystick1Button12:
break;
case KeyCode.Joystick1Button13:
break;
case KeyCode.Joystick1Button14:
break;
case KeyCode.Joystick1Button15:
break;
case KeyCode.Joystick1Button16:
break;
case KeyCode.Joystick1Button17:
break;
case KeyCode.Joystick1Button18:
break;
case KeyCode.Joystick1Button19:
break;
case KeyCode.Joystick2Button0:
break;
case KeyCode.Joystick2Button1:
break;
case KeyCode.Joystick2Button2:
break;
case KeyCode.Joystick2Button3:
break;
case KeyCode.Joystick2Button4:
break;
case KeyCode.Joystick2Button5:
break;
case KeyCode.Joystick2Button6:
break;
case KeyCode.Joystick2Button7:
break;
case KeyCode.Joystick2Button8:
break;
case KeyCode.Joystick2Button9:
break;
case KeyCode.Joystick2Button10:
break;
case KeyCode.Joystick2Button11:
break;
case KeyCode.Joystick2Button12:
break;
case KeyCode.Joystick2Button13:
break;
case KeyCode.Joystick2Button14:
break;
case KeyCode.Joystick2Button15:
break;
case KeyCode.Joystick2Button16:
break;
case KeyCode.Joystick2Button17:
break;
case KeyCode.Joystick2Button18:
break;
case KeyCode.Joystick2Button19:
break;
case KeyCode.Joystick3Button0:
break;
case KeyCode.Joystick3Button1:
break;
case KeyCode.Joystick3Button2:
break;
case KeyCode.Joystick3Button3:
break;
case KeyCode.Joystick3Button4:
break;
case KeyCode.Joystick3Button5:
break;
case KeyCode.Joystick3Button6:
break;
case KeyCode.Joystick3Button7:
break;
case KeyCode.Joystick3Button8:
break;
case KeyCode.Joystick3Button9:
break;
case KeyCode.Joystick3Button10:
break;
case KeyCode.Joystick3Button11:
break;
case KeyCode.Joystick3Button12:
break;
case KeyCode.Joystick3Button13:
break;
case KeyCode.Joystick3Button14:
break;
case KeyCode.Joystick3Button15:
break;
case KeyCode.Joystick3Button16:
break;
case KeyCode.Joystick3Button17:
break;
case KeyCode.Joystick3Button18:
break;
case KeyCode.Joystick3Button19:
break;
case KeyCode.Joystick4Button0:
break;
case KeyCode.Joystick4Button1:
break;
case KeyCode.Joystick4Button2:
break;
case KeyCode.Joystick4Button3:
break;
case KeyCode.Joystick4Button4:
break;
case KeyCode.Joystick4Button5:
break;
case KeyCode.Joystick4Button6:
break;
case KeyCode.Joystick4Button7:
break;
case KeyCode.Joystick4Button8:
break;
case KeyCode.Joystick4Button9:
break;
case KeyCode.Joystick4Button10:
break;
case KeyCode.Joystick4Button11:
break;
case KeyCode.Joystick4Button12:
break;
case KeyCode.Joystick4Button13:
break;
case KeyCode.Joystick4Button14:
break;
case KeyCode.Joystick4Button15:
break;
case KeyCode.Joystick4Button16:
break;
case KeyCode.Joystick4Button17:
break;
case KeyCode.Joystick4Button18:
break;
case KeyCode.Joystick4Button19:
break;
case KeyCode.Joystick5Button0:
break;
case KeyCode.Joystick5Button1:
break;
case KeyCode.Joystick5Button2:
break;
case KeyCode.Joystick5Button3:
break;
case KeyCode.Joystick5Button4:
break;
case KeyCode.Joystick5Button5:
break;
case KeyCode.Joystick5Button6:
break;
case KeyCode.Joystick5Button7:
break;
case KeyCode.Joystick5Button8:
break;
case KeyCode.Joystick5Button9:
break;
case KeyCode.Joystick5Button10:
break;
case KeyCode.Joystick5Button11:
break;
case KeyCode.Joystick5Button12:
break;
case KeyCode.Joystick5Button13:
break;
case KeyCode.Joystick5Button14:
break;
case KeyCode.Joystick5Button15:
break;
case KeyCode.Joystick5Button16:
break;
case KeyCode.Joystick5Button17:
break;
case KeyCode.Joystick5Button18:
break;
case KeyCode.Joystick5Button19:
break;
case KeyCode.Joystick6Button0:
break;
case KeyCode.Joystick6Button1:
break;
case KeyCode.Joystick6Button2:
break;
case KeyCode.Joystick6Button3:
break;
case KeyCode.Joystick6Button4:
break;
case KeyCode.Joystick6Button5:
break;
case KeyCode.Joystick6Button6:
break;
case KeyCode.Joystick6Button7:
break;
case KeyCode.Joystick6Button8:
break;
case KeyCode.Joystick6Button9:
break;
case KeyCode.Joystick6Button10:
break;
case KeyCode.Joystick6Button11:
break;
case KeyCode.Joystick6Button12:
break;
case KeyCode.Joystick6Button13:
break;
case KeyCode.Joystick6Button14:
break;
case KeyCode.Joystick6Button15:
break;
case KeyCode.Joystick6Button16:
break;
case KeyCode.Joystick6Button17:
break;
case KeyCode.Joystick6Button18:
break;
case KeyCode.Joystick6Button19:
break;
case KeyCode.Joystick7Button0:
break;
case KeyCode.Joystick7Button1:
break;
case KeyCode.Joystick7Button2:
break;
case KeyCode.Joystick7Button3:
break;
case KeyCode.Joystick7Button4:
break;
case KeyCode.Joystick7Button5:
break;
case KeyCode.Joystick7Button6:
break;
case KeyCode.Joystick7Button7:
break;
case KeyCode.Joystick7Button8:
break;
case KeyCode.Joystick7Button9:
break;
case KeyCode.Joystick7Button10:
break;
case KeyCode.Joystick7Button11:
break;
case KeyCode.Joystick7Button12:
break;
case KeyCode.Joystick7Button13:
break;
case KeyCode.Joystick7Button14:
break;
case KeyCode.Joystick7Button15:
break;
case KeyCode.Joystick7Button16:
break;
case KeyCode.Joystick7Button17:
break;
case KeyCode.Joystick7Button18:
break;
case KeyCode.Joystick7Button19:
break;
case KeyCode.Joystick8Button0:
break;
case KeyCode.Joystick8Button1:
break;
case KeyCode.Joystick8Button2:
break;
case KeyCode.Joystick8Button3:
break;
case KeyCode.Joystick8Button4:
break;
case KeyCode.Joystick8Button5:
break;
case KeyCode.Joystick8Button6:
break;
case KeyCode.Joystick8Button7:
break;
case KeyCode.Joystick8Button8:
break;
case KeyCode.Joystick8Button9:
break;
case KeyCode.Joystick8Button10:
break;
case KeyCode.Joystick8Button11:
break;
case KeyCode.Joystick8Button12:
break;
case KeyCode.Joystick8Button13:
break;
case KeyCode.Joystick8Button14:
break;
case KeyCode.Joystick8Button15:
break;
case KeyCode.Joystick8Button16:
break;
case KeyCode.Joystick8Button17:
break;
case KeyCode.Joystick8Button18:
break;
case KeyCode.Joystick8Button19:
break;
//default:
// throw new ArgumentOutOfRangeException(nameof(key), key, null);
}
if (!silent)
BepInEx.Logging.Logger.Log(LogLevel.Debug, $"[{nameof(NewInputSystem)}] Unsupported key: {key}");
return null;
}
}
internal class LegacyInputSystem : IInputSystem
{
[MethodImpl(MethodImplOptions.NoInlining)]
public LegacyInputSystem() => Input.GetKeyDown(KeyCode.A);
public bool GetKey(string name) => Input.GetKey(name);
public bool GetKey(KeyCode key) => Input.GetKey(key);
public bool GetKeyDown(string name) => Input.GetKeyDown(name);
public bool GetKeyDown(KeyCode key) => Input.GetKeyDown(key);
public bool GetKeyUp(string name) => Input.GetKeyUp(name);
public bool GetKeyUp(KeyCode key) => Input.GetKeyUp(key);
public bool GetMouseButton(int button) => Input.GetMouseButton(button);
public bool GetMouseButtonDown(int button) => Input.GetMouseButtonDown(button);
public bool GetMouseButtonUp(int button) => Input.GetMouseButtonUp(button);
public void ResetInputAxes() => Input.ResetInputAxes();
public Vector3 mousePosition => Input.mousePosition;
public Vector2 mouseScrollDelta => Input.mouseScrollDelta;
public bool mousePresent => Input.mousePresent;
public bool anyKey => Input.anyKey;
public bool anyKeyDown => Input.anyKeyDown;
public IEnumerable<KeyCode> SupportedKeyCodes { get; } = (KeyCode[])Enum.GetValues(typeof(KeyCode));
}
}
+57 -13
View File
@@ -1,6 +1,7 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using BepInEx.Logging;
using UnityEngine;
using UnityEngine.InputSystem;
@@ -29,18 +30,22 @@ namespace BepInEx
{
try
{
Input.GetKeyDown(KeyCode.A);
current = new LegacyInputSystem();
Logging.Logger.Log(LogLevel.Debug, "[UnityInput] Using LegacyInputSystem");
}
catch (InvalidOperationException)
{
current = new NewInputSystem();
Logging.Logger.Log(LogLevel.Debug, "[UnityInput] Using NewInputSystem");
try
{
current = new LegacyInputSystem();
BepInEx.Logging.Logger.Log(LogLevel.Debug, "[UnityInput] Using LegacyInputSystem");
}
catch
{
var newInputSystem = new NewInputSystem();
current = newInputSystem;
BepInEx.Logging.Logger.Log(LogLevel.Debug, "[UnityInput] Using NewInputSystem");
}
}
catch (Exception ex)
{
Logging.Logger.Log(LogLevel.Warning, "[UnityInput] Failed to detect available input systems - " + ex);
current = new NullInputSystem();
BepInEx.Logging.Logger.Log(LogLevel.Warning, "[UnityInput] Failed to detect available input systems - " + ex);
}
}
return current;
@@ -108,8 +113,44 @@ namespace BepInEx
IEnumerable<KeyCode> SupportedKeyCodes { get; }
}
internal class NullInputSystem : IInputSystem
{
public bool GetKey(string name) => false;
public bool GetKey(KeyCode key) => false;
public bool GetKeyDown(string name) => false;
public bool GetKeyDown(KeyCode key) => false;
public bool GetKeyUp(string name) => false;
public bool GetKeyUp(KeyCode key) => false;
public bool GetMouseButton(int button) => false;
public bool GetMouseButtonDown(int button) => false;
public bool GetMouseButtonUp(int button) => false;
public void ResetInputAxes() { }
public Vector3 mousePosition => Vector3.zero;
public Vector2 mouseScrollDelta => Vector2.zero;
public bool mousePresent => false;
public bool anyKey => false;
public bool anyKeyDown => false;
public IEnumerable<KeyCode> SupportedKeyCodes { get; } = Enumerable.Empty<KeyCode>();
}
internal class NewInputSystem : IInputSystem
{
[MethodImpl(MethodImplOptions.NoInlining)]
public NewInputSystem() => GetKeyDown(KeyCode.A);
public bool GetKey(string name) => GetControl(name)?.isPressed ?? false;
public bool GetKey(KeyCode key) => GetControl(key)?.isPressed ?? false;
@@ -810,12 +851,12 @@ namespace BepInEx
break;
case KeyCode.Joystick8Button19:
break;
//default:
// throw new ArgumentOutOfRangeException(nameof(key), key, null);
//default:
// throw new ArgumentOutOfRangeException(nameof(key), key, null);
}
if (!silent)
Logging.Logger.Log(LogLevel.Debug, $"[{nameof(NewInputSystem)}] Unsupported key: {key}");
BepInEx.Logging.Logger.Log(LogLevel.Debug, $"[{nameof(NewInputSystem)}] Unsupported key: {key}");
return null;
}
@@ -823,6 +864,9 @@ namespace BepInEx
internal class LegacyInputSystem : IInputSystem
{
[MethodImpl(MethodImplOptions.NoInlining)]
public LegacyInputSystem() => Input.GetKeyDown(KeyCode.A);
public bool GetKey(string name) => Input.GetKey(name);
public bool GetKey(KeyCode key) => Input.GetKey(key);