From f1421f61ab8628ddbae1fbd62925c56b82ccdecc Mon Sep 17 00:00:00 2001 From: TollyH Date: Fri, 26 Apr 2024 18:31:02 +0100 Subject: [PATCH] Add support for Unity's new input system --- Properties/AssemblyInfo.cs | 10 ++-- README.md | 5 +- Unity-FreeCamPlugin.cs | 98 +++++++++++++++++++++++++------------- 3 files changed, 70 insertions(+), 43 deletions(-) diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index d522f79..b3e4228 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Unity_FreeCam")] @@ -10,8 +10,8 @@ [assembly: AssemblyProduct("Unity_FreeCam")] [assembly: AssemblyCopyright("Copyright © 2024 Ptolemy Hill")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -21,11 +21,11 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion(Unity_FreeCam.FreeCamPlugin.Version)] diff --git a/README.md b/README.md index a82f435..f1a238c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Unity FreeCam -Unity BepInEx plugin for enabling free control over in-game cameras. +Unity BepInEx plugin for enabling free control over in-game cameras, with support for both the legacy and new input system. ## Contents @@ -18,9 +18,6 @@ Unity BepInEx plugin for enabling free control over in-game cameras. This plugin requires [BepInEx](https://github.com/BepInEx/BepInEx/releases/tag/v5.4.22) (ideally version `5.4.22`) to be installed in the target game. The default bindings for the keys mentioned in this section can be found below. -> [!IMPORTANT] -> Games using Unity's new input system are currently not supported. - ### Toggling the Plugin The plugin can be toggled on and off with the `Toggle FreeCam` key. When the plugin is on, input to the game will be disabled and input to the plugin will be enabled. When off, the game can be controlled as normal, however the plugin will only respond to the `Toggle FreeCam` key. Repositioned cameras will retain their new position even when toggling the plugin off, allowing you to go back to controlling the game whilst keeping the camera in your desired position. diff --git a/Unity-FreeCamPlugin.cs b/Unity-FreeCamPlugin.cs index 57998fd..984f973 100644 --- a/Unity-FreeCamPlugin.cs +++ b/Unity-FreeCamPlugin.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; using BepInEx; @@ -11,9 +12,9 @@ namespace Unity_FreeCam { [BepInPlugin(GUID, "Unity-FreeCam", Version)] public sealed class FreeCamPlugin : BaseUnityPlugin - { + { public const string GUID = "TollyH.Unity-FreeCam"; - public const string Version = "1.0.0"; + public const string Version = "1.1.0"; private static new ManualLogSource Logger; @@ -81,7 +82,15 @@ public sealed class FreeCamPlugin : BaseUnityPlugin public void Start() { - _ = Harmony.CreateAndPatchAll(typeof(FreeCamPlugin)); + Harmony harmony = new Harmony(GUID); + harmony.PatchAll(typeof(FreeCamPlugin)); + + // The methods for the new input system must only be patched if the Assembly is loaded, otherwise they won't be found + if (AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name == "Unity.InputSystem")) + { + Logger.LogDebug("New input system present - patching additional methods"); + harmony.PatchAll(typeof(NewInputSystemPatches)); + } } public void Awake() @@ -243,7 +252,7 @@ private static void ProcessInput() processingInput = true; try { - if (Input.GetKeyDown(configToggleFreecamKey.Value)) + if (UnityInput.Current.GetKeyDown(configToggleFreecamKey.Value)) { freecamActive = !freecamActive; Logger.LogMessage($"FreeCam is now {(freecamActive ? "enabled" : "disabled")}"); @@ -254,7 +263,7 @@ private static void ProcessInput() return; } - if (Input.GetKeyDown(configSelectCameraKey.Value)) + if (UnityInput.Current.GetKeyDown(configSelectCameraKey.Value)) { if (Camera.allCamerasCount == 0) { @@ -267,12 +276,12 @@ private static void ProcessInput() } } - if (Input.GetKeyDown(configListCamerasKey.Value)) + if (UnityInput.Current.GetKeyDown(configListCamerasKey.Value)) { LogCameraList(); } - if (Input.GetKeyDown(configToggleGameFreezeKey.Value)) + if (UnityInput.Current.GetKeyDown(configToggleGameFreezeKey.Value)) { gameFrozen = !gameFrozen; if (!gameFrozen) @@ -286,7 +295,7 @@ private static void ProcessInput() Logger.LogMessage($"Game is now {(gameFrozen ? "frozen" : "un-frozen")}"); } - if (Input.GetKeyDown(configToggleUIVisibilityKey.Value)) + if (UnityInput.Current.GetKeyDown(configToggleUIVisibilityKey.Value)) { hideUI = !hideUI; if (hideUI) @@ -307,19 +316,19 @@ private static void ProcessInput() Logger.LogMessage($"UI is now {(hideUI ? "hidden" : "visible")}"); } - if (Input.GetKey(configIncreaseMoveSpeedKey.Value)) + if (UnityInput.Current.GetKey(configIncreaseMoveSpeedKey.Value)) { moveSpeed += moveSpeed * Time.unscaledDeltaTime; } - if (Input.GetKey(configDecreaseMoveSpeedKey.Value)) + if (UnityInput.Current.GetKey(configDecreaseMoveSpeedKey.Value)) { moveSpeed -= moveSpeed * Time.unscaledDeltaTime; } - if (Input.GetKey(configIncreaseRotationSpeedKey.Value)) + if (UnityInput.Current.GetKey(configIncreaseRotationSpeedKey.Value)) { rotationSpeed += rotationSpeed * Time.unscaledDeltaTime; } - if (Input.GetKey(configDecreaseRotationSpeedKey.Value)) + if (UnityInput.Current.GetKey(configDecreaseRotationSpeedKey.Value)) { rotationSpeed -= rotationSpeed * Time.unscaledDeltaTime; } @@ -329,103 +338,103 @@ private static void ProcessInput() { Camera selectedCamera = Camera.allCameras[selectedCameraIndex]; - if (Input.GetKeyDown(configResetPositionKey.Value)) + if (UnityInput.Current.GetKeyDown(configResetPositionKey.Value)) { StopPositionControl(selectedCamera); } - if (Input.GetKeyDown(configResetRotationKey.Value)) + if (UnityInput.Current.GetKeyDown(configResetRotationKey.Value)) { StopRotationControl(selectedCamera); } - if (Input.GetKeyDown(configResetViewKey.Value)) + if (UnityInput.Current.GetKeyDown(configResetViewKey.Value)) { StopViewControl(selectedCamera); } - if (Input.GetKey(configMoveForwardKey.Value)) + if (UnityInput.Current.GetKey(configMoveForwardKey.Value)) { StartPositionControl(selectedCamera); overrideCameraPositions[selectedCamera] += selectedCamera.transform.TransformDirection(Vector3.forward * Time.unscaledDeltaTime * moveSpeed); } - if (Input.GetKey(configMoveBackwardKey.Value)) + if (UnityInput.Current.GetKey(configMoveBackwardKey.Value)) { StartPositionControl(selectedCamera); overrideCameraPositions[selectedCamera] += selectedCamera.transform.TransformDirection(Vector3.back * Time.unscaledDeltaTime * moveSpeed); } - if (Input.GetKey(configMoveLeftKey.Value)) + if (UnityInput.Current.GetKey(configMoveLeftKey.Value)) { StartPositionControl(selectedCamera); overrideCameraPositions[selectedCamera] += selectedCamera.transform.TransformDirection(Vector3.left * Time.unscaledDeltaTime * moveSpeed); } - if (Input.GetKey(configMoveRightKey.Value)) + if (UnityInput.Current.GetKey(configMoveRightKey.Value)) { StartPositionControl(selectedCamera); overrideCameraPositions[selectedCamera] += selectedCamera.transform.TransformDirection(Vector3.right * Time.unscaledDeltaTime * moveSpeed); } - if (Input.GetKey(configMoveUpKey.Value)) + if (UnityInput.Current.GetKey(configMoveUpKey.Value)) { StartPositionControl(selectedCamera); overrideCameraPositions[selectedCamera] += selectedCamera.transform.TransformDirection(Vector3.up * Time.unscaledDeltaTime * moveSpeed); } - if (Input.GetKey(configMoveDownKey.Value)) + if (UnityInput.Current.GetKey(configMoveDownKey.Value)) { StartPositionControl(selectedCamera); overrideCameraPositions[selectedCamera] += selectedCamera.transform.TransformDirection(Vector3.down * Time.unscaledDeltaTime * moveSpeed); } - if (Input.GetKey(configRotatePitchForwardKey.Value)) + if (UnityInput.Current.GetKey(configRotatePitchForwardKey.Value)) { StartRotationControl(selectedCamera); Vector3 currentEuler = overrideCameraRotations[selectedCamera].Value.eulerAngles; overrideCameraRotations[selectedCamera] = Quaternion.Euler(currentEuler.x - (Time.unscaledDeltaTime * rotationSpeed), currentEuler.y, currentEuler.z); } - if (Input.GetKey(configRotatePitchBackwardKey.Value)) + if (UnityInput.Current.GetKey(configRotatePitchBackwardKey.Value)) { StartRotationControl(selectedCamera); Vector3 currentEuler = overrideCameraRotations[selectedCamera].Value.eulerAngles; overrideCameraRotations[selectedCamera] = Quaternion.Euler(currentEuler.x + (Time.unscaledDeltaTime * rotationSpeed), currentEuler.y, currentEuler.z); } - if (Input.GetKey(configRotateYawLeftKey.Value)) + if (UnityInput.Current.GetKey(configRotateYawLeftKey.Value)) { StartRotationControl(selectedCamera); Vector3 currentEuler = overrideCameraRotations[selectedCamera].Value.eulerAngles; overrideCameraRotations[selectedCamera] = Quaternion.Euler(currentEuler.x, currentEuler.y - (Time.unscaledDeltaTime * rotationSpeed), currentEuler.z); } - if (Input.GetKey(configRotateYawRightKey.Value)) + if (UnityInput.Current.GetKey(configRotateYawRightKey.Value)) { StartRotationControl(selectedCamera); Vector3 currentEuler = overrideCameraRotations[selectedCamera].Value.eulerAngles; overrideCameraRotations[selectedCamera] = Quaternion.Euler(currentEuler.x, currentEuler.y + (Time.unscaledDeltaTime * rotationSpeed), currentEuler.z); } - if (Input.GetKey(configRotateRollCounterClockwiseKey.Value)) + if (UnityInput.Current.GetKey(configRotateRollCounterClockwiseKey.Value)) { StartRotationControl(selectedCamera); Vector3 currentEuler = overrideCameraRotations[selectedCamera].Value.eulerAngles; overrideCameraRotations[selectedCamera] = Quaternion.Euler(currentEuler.x, currentEuler.y, currentEuler.z + (Time.unscaledDeltaTime * rotationSpeed)); } - if (Input.GetKey(configRotateRollClockwiseKey.Value)) + if (UnityInput.Current.GetKey(configRotateRollClockwiseKey.Value)) { StartRotationControl(selectedCamera); Vector3 currentEuler = overrideCameraRotations[selectedCamera].Value.eulerAngles; overrideCameraRotations[selectedCamera] = Quaternion.Euler(currentEuler.x, currentEuler.y, currentEuler.z - (Time.unscaledDeltaTime * rotationSpeed)); } - if (Input.GetKey(configIncreaseFovKey.Value)) + if (UnityInput.Current.GetKey(configIncreaseFovKey.Value)) { StartViewControl(selectedCamera); overrideCameraFovs[selectedCamera] += Time.unscaledDeltaTime * rotationSpeed; } - if (Input.GetKey(configDecreaseFovKey.Value)) + if (UnityInput.Current.GetKey(configDecreaseFovKey.Value)) { StartViewControl(selectedCamera); overrideCameraFovs[selectedCamera] -= Time.unscaledDeltaTime * rotationSpeed; } - if (Input.GetKey(configIncreaseNearClipKey.Value)) + if (UnityInput.Current.GetKey(configIncreaseNearClipKey.Value)) { StartViewControl(selectedCamera); overrideCameraNearClips[selectedCamera] += Time.unscaledDeltaTime * moveSpeed; } - if (Input.GetKey(configDecreaseNearClipKey.Value)) + if (UnityInput.Current.GetKey(configDecreaseNearClipKey.Value)) { StartViewControl(selectedCamera); overrideCameraNearClips[selectedCamera] -= Time.unscaledDeltaTime * moveSpeed; @@ -434,12 +443,12 @@ private static void ProcessInput() overrideCameraNearClips[selectedCamera] = 0.01f; } } - if (Input.GetKey(configIncreaseFarClipKey.Value)) + if (UnityInput.Current.GetKey(configIncreaseFarClipKey.Value)) { StartViewControl(selectedCamera); overrideCameraFarClips[selectedCamera] += Time.unscaledDeltaTime * moveSpeed; } - if (Input.GetKey(configDecreaseFarClipKey.Value)) + if (UnityInput.Current.GetKey(configDecreaseFarClipKey.Value)) { StartViewControl(selectedCamera); overrideCameraFarClips[selectedCamera] -= Time.unscaledDeltaTime * moveSpeed; @@ -522,6 +531,27 @@ public static bool OverrideKeybinds(ref bool __result) return true; } + public static class NewInputSystemPatches + { + [HarmonyPrefix] + [HarmonyPatch("UnityEngine.InputSystem.Controls.ButtonControl, Unity.InputSystem", "IsValueConsideredPressed")] + [HarmonyPatch("UnityEngine.InputSystem.Controls.ButtonControl, Unity.InputSystem", "isPressed", MethodType.Getter)] + [HarmonyPatch("UnityEngine.InputSystem.Controls.ButtonControl, Unity.InputSystem", "wasPressedThisFrame", MethodType.Getter)] + [HarmonyPatch("UnityEngine.InputSystem.InputAction, Unity.InputSystem", "IsPressed")] + [HarmonyPatch("UnityEngine.InputSystem.InputAction, Unity.InputSystem", "IsInProgress")] + [HarmonyPatch("UnityEngine.InputSystem.InputAction, Unity.InputSystem", "WasPressedThisFrame")] + [HarmonyPatch("UnityEngine.InputSystem.InputAction, Unity.InputSystem", "WasPerformedThisFrame")] + public static bool OverrideNewKeybinds(ref bool __result) + { + if (freecamActive && !processingInput) + { + __result = false; + return false; + } + return true; + } + } + public static string GetFullHierarchyPath(GameObject gameObject) { StringBuilder sb = new StringBuilder(gameObject.name);