using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using TheLabModdingLib; using UnityEngine; using UnityEngine.SceneManagement; using Valve.VR.InteractionSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace SmoothLocomotion; [BepInPlugin("com.thelab.smoothlocomotion", "SmoothLocomotion", "1.0.0")] public class SmoothLocomotionMod : BaseUnityPlugin { private ConfigEntry configEnabled; private ConfigEntry configMoveSpeed; private ConfigEntry configSnapTurn; private ConfigEntry configSnapTurnAngle; private ConfigEntry configDeadzone; private ConfigEntry configNoClip; private ConfigEntry configGravityScale; private float moveSpeed = 2f; private float snapTurnAngle = 45f; private float deadzone = 0.2f; private bool smoothLocomotionEnabled = true; private bool snapTurningEnabled = true; private bool noClip = false; private float gravityScale = 1f; private Vector2 lastRightStick; private CharacterController _cc; private int _lastIgnoreFrame = -1; private float _verticalVelocity = 0f; private float _maxHeadHeight = 0f; private void Awake() { configEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable smooth locomotion"); configMoveSpeed = ((BaseUnityPlugin)this).Config.Bind("General", "MoveSpeed", 2f, "Movement speed (units/sec)"); configSnapTurn = ((BaseUnityPlugin)this).Config.Bind("General", "SnapTurnEnabled", true, "Enable snap turning"); configSnapTurnAngle = ((BaseUnityPlugin)this).Config.Bind("General", "SnapTurnAngle", 45f, "Snap turn angle (degrees)"); configDeadzone = ((BaseUnityPlugin)this).Config.Bind("General", "Deadzone", 0.2f, "Thumbstick deadzone"); configNoClip = ((BaseUnityPlugin)this).Config.Bind("General", "NoClip", false, "Disable collision when moving"); configGravityScale = ((BaseUnityPlugin)this).Config.Bind("General", "GravityScale", 1f, "Gravity multiplier (1 = normal)"); smoothLocomotionEnabled = configEnabled.Value; moveSpeed = configMoveSpeed.Value; snapTurningEnabled = configSnapTurn.Value; snapTurnAngle = configSnapTurnAngle.Value; deadzone = configDeadzone.Value; noClip = configNoClip.Value; gravityScale = configGravityScale.Value; configEnabled.SettingChanged += delegate { smoothLocomotionEnabled = configEnabled.Value; }; configMoveSpeed.SettingChanged += delegate { moveSpeed = configMoveSpeed.Value; }; configSnapTurn.SettingChanged += delegate { snapTurningEnabled = configSnapTurn.Value; }; configSnapTurnAngle.SettingChanged += delegate { snapTurnAngle = configSnapTurnAngle.Value; }; configDeadzone.SettingChanged += delegate { deadzone = configDeadzone.Value; }; configGravityScale.SettingChanged += delegate { gravityScale = configGravityScale.Value; }; configNoClip.SettingChanged += delegate { noClip = configNoClip.Value; if (noClip && (Object)(object)_cc != (Object)null) { Object.Destroy((Object)(object)_cc); _cc = null; } if (!noClip) { _cc = null; } }; InputAPI.Initialize(); SceneManager.sceneLoaded += OnSceneLoaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[SmoothLocomotion] Initialized."); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { _cc = null; _maxHeadHeight = 0f; _verticalVelocity = 0f; if (smoothLocomotionEnabled) { try { PlayerAPI.SetTeleportEnabled(false); } catch { } } } private void Update() { if (!smoothLocomotionEnabled) { return; } try { if (!((Object)(object)PlayerAPI.VRPlayerInstance == (Object)null)) { EnsureCC(); ProcessSmoothMovement(); ProcessSnapTurning(); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[SmoothLocomotion] Update error: " + ex.Message)); } } private void EnsureCC() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!noClip && !((Object)(object)_cc != (Object)null)) { Transform trackingOrigin = PlayerAPI.TrackingOrigin; if (!((Object)(object)trackingOrigin == (Object)null)) { _cc = ((Component)trackingOrigin).gameObject.AddComponent(); _cc.height = 1.5f; _cc.center = new Vector3(0f, 0.75f, 0f); _cc.radius = 0.2f; _cc.skinWidth = 0.01f; _cc.minMoveDistance = 0.001f; } } } private void IgnoreHandColliders() { if ((Object)(object)_cc == (Object)null || Time.frameCount == _lastIgnoreFrame) { return; } _lastIgnoreFrame = Time.frameCount; foreach (VRHand allHand in PlayerAPI.GetAllHands()) { if ((Object)(object)allHand == (Object)null) { continue; } Collider[] componentsInChildren = ((Component)allHand).GetComponentsInChildren(true); foreach (Collider val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)_cc) { Physics.IgnoreCollision((Collider)(object)_cc, val, true); } } } } private void SyncCCUnderCamera() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cc == (Object)null)) { Transform trackingOrigin = PlayerAPI.TrackingOrigin; Transform hMDTransform = PlayerAPI.HMDTransform; if (!((Object)(object)trackingOrigin == (Object)null) && !((Object)(object)hMDTransform == (Object)null)) { Vector3 val = trackingOrigin.InverseTransformPoint(hMDTransform.position); Vector3 val2 = trackingOrigin.InverseTransformDirection(hMDTransform.forward); _maxHeadHeight = Mathf.Max(new float[3] { _maxHeadHeight, val.y, 0.3f }); _cc.center = new Vector3(val.x, _maxHeadHeight * 0.5f, val.z) - val2 * 0.1f; _cc.height = _maxHeadHeight; } } } private void ProcessSmoothMovement() { //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) IgnoreHandColliders(); SyncCCUnderCamera(); Transform trackingOrigin = PlayerAPI.TrackingOrigin; Transform hMDTransform = PlayerAPI.HMDTransform; if ((Object)(object)trackingOrigin == (Object)null || (Object)(object)hMDTransform == (Object)null) { return; } Vector3 val; if ((Object)(object)_cc != (Object)null) { float num = Physics.gravity.y * gravityScale; float deltaTime = Time.deltaTime; if (_cc.isGrounded && _verticalVelocity < 0f) { _verticalVelocity = -2f * gravityScale; } else if (!_cc.isGrounded) { _verticalVelocity += num * deltaTime; } Vector2 leftThumbstickAxisNormalized = InputAPI.GetLeftThumbstickAxisNormalized(); if (((Vector2)(ref leftThumbstickAxisNormalized)).magnitude > deadzone) { val = Vector3.ProjectOnPlane(hMDTransform.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val)).normalized; val = Vector3.ProjectOnPlane(hMDTransform.right, Vector3.up); Vector3 normalized2 = ((Vector3)(ref val)).normalized; val = normalized * leftThumbstickAxisNormalized.y + normalized2 * leftThumbstickAxisNormalized.x; Vector3 normalized3 = ((Vector3)(ref val)).normalized; float num2 = moveSpeed * Mathf.Clamp01(((Vector2)(ref leftThumbstickAxisNormalized)).magnitude); _cc.Move(normalized3 * num2 * deltaTime + new Vector3(0f, _verticalVelocity * deltaTime, 0f)); } else { _cc.Move(new Vector3(0f, _verticalVelocity * deltaTime, 0f)); } } else { Vector2 leftThumbstickAxisNormalized2 = InputAPI.GetLeftThumbstickAxisNormalized(); if (((Vector2)(ref leftThumbstickAxisNormalized2)).magnitude > deadzone) { val = Vector3.ProjectOnPlane(hMDTransform.forward, Vector3.up); Vector3 normalized4 = ((Vector3)(ref val)).normalized; val = Vector3.ProjectOnPlane(hMDTransform.right, Vector3.up); Vector3 normalized5 = ((Vector3)(ref val)).normalized; val = normalized4 * leftThumbstickAxisNormalized2.y + normalized5 * leftThumbstickAxisNormalized2.x; Vector3 normalized6 = ((Vector3)(ref val)).normalized; float num3 = moveSpeed * Mathf.Clamp01(((Vector2)(ref leftThumbstickAxisNormalized2)).magnitude); trackingOrigin.position += normalized6 * num3 * Time.deltaTime; } } } private void ProcessSnapTurning() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if (!snapTurningEnabled) { return; } Vector2 rightThumbstickAxisNormalized = InputAPI.GetRightThumbstickAxisNormalized(); if (((Vector2)(ref rightThumbstickAxisNormalized)).magnitude < deadzone) { lastRightStick = Vector2.zero; return; } Transform trackingOrigin = PlayerAPI.TrackingOrigin; Transform hMDTransform = PlayerAPI.HMDTransform; if (!((Object)(object)trackingOrigin == (Object)null) && !((Object)(object)hMDTransform == (Object)null)) { if (rightThumbstickAxisNormalized.x < -0.5f && lastRightStick.x >= -0.5f) { trackingOrigin.RotateAround(hMDTransform.position, Vector3.up, 0f - snapTurnAngle); } else if (rightThumbstickAxisNormalized.x > 0.5f && lastRightStick.x <= 0.5f) { trackingOrigin.RotateAround(hMDTransform.position, Vector3.up, snapTurnAngle); } lastRightStick = rightThumbstickAxisNormalized; } } }