1
0
mirror of https://github.com/originalnicodr/CinematicUnityExplorer.git synced 2026-10-10 04:53:15 +08:00

Refactored the game's input blocker system so we only patch the legacy input system (for now) without affecting the behavior of Unity's new input system, or where none is detected.

This commit is contained in:
originalnicodr
2024-02-07 00:45:50 -03:00
parent e732672e0a
commit f34c02eeaf
5 changed files with 186 additions and 86 deletions
+170 -75
View File
@@ -2,6 +2,7 @@ using System.Collections.Generic;
using HarmonyLib;
using UnityEngine;
using UnityExplorer;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib.Input;
@@ -12,129 +13,249 @@ using IL2CPPUtils = UnhollowerBaseLib.UnhollowerUtils;
using IL2CPPUtils = Il2CppInterop.Common.Il2CppInteropUtils;
#endif
namespace UnityExplorer
namespace UniverseLib.Input
{
public class IInputManager {
private static Dictionary<KeyCode, bool> getKeyDict = new Dictionary<KeyCode, bool>();
private static Dictionary<KeyCode, bool> getKeyDownDict = new Dictionary<KeyCode, bool>();
private static Dictionary<KeyCode, bool> getKeyUpDict = new Dictionary<KeyCode, bool>();
private static Dictionary<int, bool> getMouseButton = new Dictionary<int, bool>();
private static Dictionary<int, bool> getMouseButtonDown = new Dictionary<int, bool>();
public static Vector3 MousePosition => InputManager.MousePosition;
public static class IInputManager {
// TODO: Refactor this to have the input system used on the game saved in a variable,
// and just call the methods of this variable in each function, like a proper wrapper.
private static InputType currentInputType;
public static void Setup(){
#if MONO
Type inputClass = typeof(Input);
#endif
#if CPP
Type inputClass = typeof(InputManager);
#endif
try
{
MethodInfo getKeyTarget = inputClass.GetMethod("GetKey", new Type[] {typeof(string)});
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideKeyString))));
currentInputType = InputManager.CurrentType;
switch(currentInputType){
case InputType.Legacy:
ILegacyInput.Init();
break;
case InputType.InputSystem:
case InputType.None:
break;
}
catch { }
}
public static bool GetKey(KeyCode key){
switch(currentInputType){
case InputType.Legacy:
return ILegacyInput.GetKey(key);
case InputType.InputSystem:
case InputType.None:
default:
return InputManager.GetKey(key);
}
}
public static bool GetKeyDown(KeyCode key){
switch(currentInputType){
case InputType.Legacy:
return ILegacyInput.GetKeyDown(key);
case InputType.InputSystem:
case InputType.None:
default:
return InputManager.GetKeyDown(key);
}
}
public static bool GetKeyUp(KeyCode key){
switch(currentInputType){
case InputType.Legacy:
return ILegacyInput.GetKeyUp(key);
case InputType.InputSystem:
case InputType.None:
default:
return InputManager.GetKeyUp(key);
}
}
public static bool GetMouseButton(int button){
switch(currentInputType){
case InputType.Legacy:
return ILegacyInput.GetMouseButton(button);
case InputType.InputSystem:
case InputType.None:
default:
return InputManager.GetMouseButton(button);
}
}
public static bool GetMouseButtonDown(int button){
switch(currentInputType){
case InputType.Legacy:
return ILegacyInput.GetMouseButtonDown(button);
case InputType.InputSystem:
case InputType.None:
default:
return InputManager.GetMouseButtonDown(button);
}
}
public static Vector3 MousePosition => currentInputType == InputType.Legacy ? (Vector3)ILegacyInput.MousePosition : (Vector3)InputManager.MousePosition;
}
public static class ILegacyInput {
public static Dictionary<KeyCode, bool> getKeyDict = new Dictionary<KeyCode, bool>();
public static Dictionary<KeyCode, bool> getKeyDownDict = new Dictionary<KeyCode, bool>();
public static Dictionary<KeyCode, bool> getKeyUpDict = new Dictionary<KeyCode, bool>();
public static Dictionary<int, bool> getMouseButton = new Dictionary<int, bool>();
public static Dictionary<int, bool> getMouseButtonDown = new Dictionary<int, bool>();
public static Vector3 MousePosition;
// Wrapped methods
public static bool GetKey(KeyCode key){
if (key == KeyCode.None) return false;
// Trigger the original InputManager method
InputManager.GetKey(key);
return getKeyDict[key];
}
public static bool GetKeyDown(KeyCode key){
if (key == KeyCode.None) return false;
// Trigger the original InputManager method
InputManager.GetKeyDown(key);
return getKeyDownDict[key];
}
public static bool GetKeyUp(KeyCode key){
if (key == KeyCode.None) return false;
// Trigger the original InputManager method
InputManager.GetKeyUp(key);
return getKeyUpDict[key];
}
public static bool GetMouseButton(int button){
// Trigger the original InputManager method
InputManager.GetMouseButton(button);
return getMouseButton[button];
}
public static bool GetMouseButtonDown(int button){
// Trigger the original InputManager method
InputManager.GetMouseButtonDown(button);
return getMouseButtonDown[button];
}
// Patch the input methods of the legacy input system
public static void Init(){
Type t_Input = ReflectionUtility.GetTypeByName("UnityEngine.Input");
try
{
MethodInfo getKeyTarget = inputClass.GetMethod("GetKey", new Type[] {typeof(KeyCode)});
MethodInfo getKeyTarget = t_Input.GetMethod("GetKey", new Type[] {typeof(string)});
//ExplorerCore.LogWarning(getKeyTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideKeyKeyCode))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideKeyString))));
}
catch { }
try
{
MethodInfo getKeyTarget = t_Input.GetMethod("GetKey", new Type[] {typeof(KeyCode)});
//ExplorerCore.LogWarning(getKeyTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyTarget,
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideKeyKeyCode))));
}
catch { }
try
{
MethodInfo getKeyDownTarget = inputClass.GetMethod("GetKeyDown", new Type[] {typeof(string)});
MethodInfo getKeyDownTarget = t_Input.GetMethod("GetKeyDown", new Type[] {typeof(string)});
//ExplorerCore.LogWarning(getKeyDownTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyDownTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyDownTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideKeyDownString))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideKeyDownString))));
}
catch { }
try
{
MethodInfo getKeyDownTarget = inputClass.GetMethod("GetKeyDown", new Type[] {typeof(KeyCode)});
MethodInfo getKeyDownTarget = t_Input.GetMethod("GetKeyDown", new Type[] {typeof(KeyCode)});
//ExplorerCore.LogWarning(getKeyDownTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyDownTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyDownTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideKeyDownKeyCode))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideKeyDownKeyCode))));
}
catch { }
try
{
MethodInfo getKeyUpTarget = inputClass.GetMethod("GetKeyUp", new Type[] {typeof(string)});
MethodInfo getKeyUpTarget = t_Input.GetMethod("GetKeyUp", new Type[] {typeof(string)});
//ExplorerCore.LogWarning(getKeyUpTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyUpTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyUpTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideKeyUpString))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideKeyUpString))));
}
catch { }
try
{
MethodInfo getKeyUpTarget = inputClass.GetMethod("GetKeyUp", new Type[] {typeof(KeyCode)});
MethodInfo getKeyUpTarget = t_Input.GetMethod("GetKeyUp", new Type[] {typeof(KeyCode)});
//ExplorerCore.LogWarning(getKeyUpTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getKeyUpTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getKeyUpTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideKeyUpKeyCode))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideKeyUpKeyCode))));
}
catch { }
try
{
MethodInfo getMouseButtonTarget = inputClass.GetMethod("GetMouseButton", new Type[] {typeof(int)});
MethodInfo getMouseButtonTarget = t_Input.GetMethod("GetMouseButton", new Type[] {typeof(int)});
//ExplorerCore.LogWarning(getMouseButtonTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getMouseButtonTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getMouseButtonTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideMouseButton))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideMouseButton))));
}
catch { }
try
{
MethodInfo getMouseButtonDownTarget = inputClass.GetMethod("GetMouseButtonDown", new Type[] {typeof(int)});
MethodInfo getMouseButtonDownTarget = t_Input.GetMethod("GetMouseButtonDown", new Type[] {typeof(int)});
//ExplorerCore.LogWarning(getMouseButtonDownTarget);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getMouseButtonDownTarget) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getMouseButtonDownTarget,
postfix: new(AccessTools.Method(typeof(IInputManager), nameof(OverrideMouseButtonDown))));
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideMouseButtonDown))));
}
catch { }
try
{
MethodInfo getMousePositionMethod = t_Input.GetProperty("mousePosition").GetGetMethod();
//ExplorerCore.LogWarning(getMousePositionMethod);
#if CPP
if (IL2CPPUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(getMousePositionMethod) == null)
return;
#endif
ExplorerCore.Harmony.Patch(getMousePositionMethod,
postfix: new(AccessTools.Method(typeof(ILegacyInput), nameof(OverrideMousePosition))));
}
catch { }
}
// Postfix functions
@@ -211,44 +332,18 @@ namespace UnityExplorer
getMouseButtonDown[button] = __result;
// Since UnityExplorer uses Unity's native UI for its menu, we can't switch off the mouse interaction with it on this wrapper.
// Therefore, if we still want to interact with the Unity Explorer menu we would need to let the button action pass through when it's open.
if (FreeCamPanel.ShouldOverrideInput() && button != 0){
if (FreeCamPanel.ShouldOverrideInput() && !(button == 0 && UIManager.ShowMenu)){
__result = false;
}
}
// Wrapped methods
public static void OverrideMousePosition(ref Vector3 __result)
{
MousePosition = __result;
public static bool GetKey(KeyCode key){
if (key == KeyCode.None) return false;
// Trigger the original InputManager method
InputManager.GetKey(key);
return getKeyDict[key];
}
public static bool GetKeyDown(KeyCode key){
if (key == KeyCode.None) return false;
// Trigger the original InputManager method
InputManager.GetKeyDown(key);
return getKeyDownDict[key];
}
public static bool GetKeyUp(KeyCode key){
if (key == KeyCode.None) return false;
// Trigger the original InputManager method
InputManager.GetKeyUp(key);
return getKeyUpDict[key];
}
public static bool GetMouseButton(int button){
// Trigger the original InputManager method
InputManager.GetMouseButton(button);
return getMouseButton[button];
}
public static bool GetMouseButtonDown(int button){
// Trigger the original InputManager method
InputManager.GetMouseButtonDown(button);
return getMouseButtonDown[button];
if (FreeCamPanel.ShouldOverrideInput() && !UIManager.ShowMenu){
__result = Vector3.zero;
}
}
}
}
+2 -1
View File
@@ -204,7 +204,8 @@ namespace UnityExplorer.Config
KeyCode.Home);
Toggle_Block_Games_Input = new("Toggle block games input",
"Blocks the games input when the the freecam is on.",
"Blocks the games input when the the freecam is on.\n" +
"If you don't see a 'Block games input on Freecam' checkbox on the FreecCam panel then it's not supported for this game.",
KeyCode.KeypadPeriod);
Speed_Up_Movement = new("Speed up movement",
+1 -1
View File
@@ -139,7 +139,7 @@ namespace UnityExplorer
FreeCamPanel.blockFreecamMovementToggle.isOn = !FreeCamPanel.blockFreecamMovementToggle.isOn;
}
if (IInputManager.GetKeyDown(ConfigManager.Toggle_Block_Games_Input.Value))
if (FreeCamPanel.supportedInput && IInputManager.GetKeyDown(ConfigManager.Toggle_Block_Games_Input.Value))
{
FreeCamPanel.blockGamesInputOnFreecamToggle.isOn = !FreeCamPanel.blockGamesInputOnFreecamToggle.isOn;
}
+2 -1
View File
@@ -59,7 +59,6 @@ namespace UnityExplorer
//Extra inits
KeypressListener.Setup();
IInputManager.Setup();
ArrowGenerator.PatchLights();
}
@@ -76,6 +75,8 @@ namespace UnityExplorer
Log($"{NAME} {VERSION} ({Universe.Context}) initialized.");
IInputManager.Setup();
// InspectorManager.Inspect(typeof(Tests.TestClass));
}
+11 -8
View File
@@ -57,6 +57,8 @@ namespace UnityExplorer.UI.Panels
static ButtonRef inspectButton;
static bool disabledCinemachine;
public static bool supportedInput => InputManager.CurrentType == InputType.Legacy;
static InputFieldRef nearClipPlaneInput;
static Slider nearClipPlaneSlider;
static float nearClipPlaneValue;
@@ -195,7 +197,7 @@ namespace UnityExplorer.UI.Panels
return;
if (ourCamera){
IEnumerable<Behaviour> comps = ourCamera.GetComponents<Behaviour>();
IEnumerable<Behaviour> comps = ourCamera.GetComponentsInChildren<Behaviour>();
foreach (Behaviour comp in comps)
{
if (comp.GetType().ToString() == "Cinemachine.CinemachineBrain"){
@@ -330,13 +332,14 @@ namespace UnityExplorer.UI.Panels
blockFreecamMovementToggle.isOn = false;
blockFreecamMovementText.text = "Block Freecam movement";
GameObject blockGamesInputOnFreecam = UIFactory.CreateToggle(togglesRow, "blockGamesInputOnFreecam", out blockGamesInputOnFreecamToggle, out Text blockGamesInputOnFreecamText);
UIFactory.SetLayoutElement(blockGamesInputOnFreecam, minHeight: 25, flexibleWidth: 9999);
blockGamesInputOnFreecamToggle.isOn = true;
blockGamesInputOnFreecamText.text = "Block games input on Freecam";
AddSpacer(5);
if (supportedInput){
GameObject blockGamesInputOnFreecam = UIFactory.CreateToggle(togglesRow, "blockGamesInputOnFreecam", out blockGamesInputOnFreecamToggle, out Text blockGamesInputOnFreecamText);
UIFactory.SetLayoutElement(blockGamesInputOnFreecam, minHeight: 25, flexibleWidth: 9999);
blockGamesInputOnFreecamToggle.isOn = true;
blockGamesInputOnFreecamText.text = "Block games input on Freecam";
AddSpacer(5);
}
string instructions = "Controls:\n" +
$"- {ConfigManager.Forwards_1.Value},{ConfigManager.Backwards_1.Value},{ConfigManager.Left_1.Value},{ConfigManager.Right_1.Value} / {ConfigManager.Forwards_2.Value},{ConfigManager.Backwards_2.Value},{ConfigManager.Left_2.Value},{ConfigManager.Right_2.Value}: Movement\n" +
@@ -352,7 +355,7 @@ namespace UnityExplorer.UI.Panels
"Extra:\n" +
$"- {ConfigManager.Freecam_Toggle.Value}: Freecam toggle\n" +
$"- {ConfigManager.Block_Freecam_Movement.Value}: Toggle block Freecam\n" +
$"- {ConfigManager.Toggle_Block_Games_Input.Value}: Toggle games input on Freecam\n" +
(supportedInput ? $"- {ConfigManager.Toggle_Block_Games_Input.Value}: Toggle games input on Freecam\n" : "") +
$"- {ConfigManager.HUD_Toggle.Value}: HUD toggle\n" +
$"- {ConfigManager.Pause.Value}: Pause\n" +
$"- {ConfigManager.Frameskip.Value}: Frameskip\n";