├── .gitattributes ├── .gitignore ├── BendyVRPatcher ├── Patcher.cs ├── Properties │ └── AssemblyInfo.cs ├── classdata.tpk └── obj │ ├── BendyVRPatcher.csproj.nuget.dgspec.json │ ├── BendyVRPatcher.csproj.nuget.g.props │ ├── BendyVRPatcher.csproj.nuget.g.targets │ ├── project.assets.json │ └── x64 │ ├── Debug │ └── BendyVRPatcher.GeneratedMSBuildEditorConfig.editorconfig │ └── Release │ ├── BendyVRPatcher.GeneratedMSBuildEditorConfig.editorconfig │ ├── BendyVRPatcher.csproj.CopyComplete │ └── BendyVRPatcher.csproj.FileListAbsolute.txt ├── BendyVR_5 ├── .gitattributes ├── .gitignore ├── BendyVRAssets │ ├── AssetBundles │ │ ├── vrhands │ │ └── vrhands.manifest │ └── Bindings │ │ ├── actions.json │ │ ├── binding_holographic_hmd.json │ │ ├── binding_index_hmd.json │ │ ├── binding_rift.json │ │ ├── binding_vive.json │ │ ├── binding_vive_cosmos.json │ │ ├── binding_vive_pro.json │ │ ├── binding_vive_tracker_camera.json │ │ ├── bindings_holographic_controller.json │ │ ├── bindings_knuckles.json │ │ ├── bindings_oculus_touch.json │ │ ├── bindings_vive_controller.json │ │ └── bindings_vive_cosmos_controller.json ├── LICENSE ├── ModFiles │ ├── BepInEx │ │ ├── config │ │ │ └── BepInEx.cfg │ │ └── core │ │ │ ├── 0Harmony.xml │ │ │ ├── BepInEx.Harmony.xml │ │ │ ├── BepInEx.Preloader.xml │ │ │ ├── BepInEx.xml │ │ │ ├── MonoMod.RuntimeDetour.xml │ │ │ └── MonoMod.Utils.xml │ ├── CopyToGame │ │ ├── Bendy and the Ink Machine_Data │ │ │ └── Plugins │ │ │ │ └── openvr_mod.cfg │ │ └── doorstop_config.ini │ ├── icon.png │ └── manifest.json ├── NuGet.Config └── src │ ├── Assets │ └── VrAssetLoader.cs │ ├── BendyVRBehavior.cs │ ├── BendyVRMod.cs │ ├── BendyVRPatch.cs │ ├── Chapters │ └── Patches │ │ ├── CH1Fixes.cs │ │ ├── CH2Fixes.cs │ │ ├── CH3Fixes.cs │ │ ├── CH4Fixes.cs │ │ ├── CH5Fixes.cs │ │ └── MiniGameFixes.cs │ ├── Debugging │ └── GeneralDebugger.cs │ ├── Helpers │ ├── CopyLocalTransformValues.cs │ ├── FakeParenting.cs │ ├── LayerHelper.cs │ ├── Logs.cs │ ├── MaterialHelper.cs │ ├── MathHelper.cs │ ├── ShaderProperty.cs │ └── TagHelper.cs │ ├── LaserPointer │ └── VrLaser.cs │ ├── Player │ ├── Patches │ │ ├── HoldableItemPatches.cs │ │ └── PlayerControllerPatches.cs │ └── VRPlayerController.cs │ ├── Settings │ ├── Patches │ │ └── GameSettingsPatches.cs │ └── VrSettings.cs │ ├── UI │ ├── CanvasToWorldSpace.cs │ └── Patches │ │ ├── CanvasToWorldSpacePatches.cs │ │ ├── MainMenuPatches.cs │ │ ├── PauseMenuPatches.cs │ │ ├── SettingsMenuPatches.cs │ │ ├── TutorialPatches.cs │ │ └── UIPatches.cs │ ├── VRCore │ ├── Patches │ │ └── StagePatches.cs │ └── VrCore.cs │ ├── VeryLateUpdateManager.cs │ ├── VrCamera │ ├── FadeOverlay.cs │ ├── Patches │ │ ├── GameCameraPatches.cs │ │ └── UICameraPatches.cs │ ├── UICameraManager.cs │ └── VrCameraManager.cs │ └── VrInput │ ├── ActionInputs │ ├── ActionInput.cs │ ├── ActionInputDefinitions.cs │ ├── BooleanActionInput.cs │ ├── EmptyActionInput.cs │ ├── IActionInput.cs │ └── Vector2ActionInput.cs │ ├── BindingsManager.cs │ ├── CommandName.cs │ ├── Patches │ ├── BindingsPatches.cs │ ├── InputManagerPatches.cs │ ├── InputPromptsPatches.cs │ ├── MousePatches.cs │ └── PlayerInputPatches.cs │ └── VirtualKey.cs ├── Directory.Build.props ├── LICENSE ├── README.md └── WebsiteAssets ├── BendyVRGithub.jpg └── reddit_mobile_1280_384.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Uu]ser[Ss]ettings/ 12 | 13 | bin/** 14 | 15 | # MemoryCaptures can get excessive in size. 16 | # They also could contain extremely sensitive data 17 | /[Mm]emoryCaptures/ 18 | 19 | # Recordings can get excessive in size 20 | /[Rr]ecordings/ 21 | 22 | # Uncomment this line if you wish to ignore the asset store tools plugin 23 | # /[Aa]ssets/AssetStoreTools* 24 | 25 | # Autogenerated Jetbrains Rider plugin 26 | /[Aa]ssets/Plugins/Editor/JetBrains* 27 | 28 | # Visual Studio cache directory 29 | .vs/ 30 | 31 | # Gradle cache directory 32 | .gradle/ 33 | 34 | # Autogenerated VS/MD/Consulo solution and project files 35 | ExportedObj/ 36 | .consulo/ 37 | *.csproj 38 | *.unityproj 39 | *.sln 40 | *.suo 41 | *.tmp 42 | *.user 43 | *.userprefs 44 | *.pidb 45 | *.booproj 46 | *.svd 47 | *.pdb 48 | *.mdb 49 | *.opendb 50 | *.VC.db 51 | 52 | # Unity3D generated meta files 53 | *.pidb.meta 54 | *.pdb.meta 55 | *.mdb.meta 56 | 57 | # Unity3D generated file on crash reports 58 | sysinfo.txt 59 | 60 | # Builds 61 | *.apk 62 | *.aab 63 | *.unitypackage 64 | *.app 65 | 66 | # Crashlytics generated file 67 | crashlytics-build.properties 68 | 69 | # Packed Addressables 70 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* 71 | 72 | # Temporary auto-generated Android Assets 73 | /[Aa]ssets/[Ss]treamingAssets/aa.meta 74 | /[Aa]ssets/[Ss]treamingAssets/aa/* 75 | -------------------------------------------------------------------------------- /BendyVRPatcher/Patcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Reflection; 6 | using Mono.Cecil; 7 | using AssetsTools.NET; 8 | using AssetsTools.NET.Extra; 9 | 10 | public static class Patcher 11 | { 12 | public static IEnumerable TargetDLLs { get; } = new[] {"Assembly-CSharp.dll"}; 13 | 14 | public static void Patch(AssemblyDefinition assembly) 15 | { 16 | } 17 | 18 | public static void Initialize() 19 | { 20 | Console.WriteLine("Patching Bendy VR..."); 21 | 22 | var installerPath = Assembly.GetExecutingAssembly().Location; 23 | Console.WriteLine("installerPath " + installerPath); 24 | 25 | var gameExePath = Process.GetCurrentProcess().MainModule.FileName; 26 | Console.WriteLine("gameExePath " + gameExePath); 27 | 28 | var gamePath = Path.GetDirectoryName(gameExePath); 29 | var gameName = Path.GetFileNameWithoutExtension(gameExePath); 30 | var dataPath = Path.Combine(gamePath, $"{gameName}_Data/"); 31 | var gameManagersPath = Path.Combine(dataPath, $"globalgamemanagers"); 32 | var gameManagersBackupPath = CreateGameManagersBackup(gameManagersPath); 33 | var patcherPath = Path.GetDirectoryName(installerPath); 34 | var classDataPath = Path.Combine(patcherPath, "classdata.tpk"); 35 | 36 | PatchVR(gameManagersBackupPath, gameManagersPath, classDataPath); 37 | 38 | Console.WriteLine($""); 39 | Console.WriteLine("Installed successfully, probably."); 40 | } 41 | 42 | private static string CreateGameManagersBackup(string gameManagersPath) 43 | { 44 | Console.WriteLine($"Backing up '{gameManagersPath}'..."); 45 | var backupPath = gameManagersPath + ".bak"; 46 | if (File.Exists(backupPath)) 47 | { 48 | Console.WriteLine($"Backup already exists."); 49 | return backupPath; 50 | } 51 | 52 | File.Copy(gameManagersPath, backupPath); 53 | Console.WriteLine($"Created backup in '{backupPath}'"); 54 | return backupPath; 55 | } 56 | 57 | private static void PatchVR(string gameManagersBackupPath, string gameManagersPath, string classDataPath) 58 | { 59 | Console.WriteLine($"Using classData file from path '{classDataPath}'"); 60 | 61 | var am = new AssetsManager(); 62 | am.LoadClassPackage(classDataPath); 63 | var ggm = am.LoadAssetsFile(gameManagersBackupPath, false); 64 | var ggmFile = ggm.file; 65 | var ggmTable = ggm.table; 66 | am.LoadClassDatabaseFromPackage(ggmFile.typeTree.unityVersion); 67 | 68 | var replacers = new List(); 69 | 70 | var buildSettings = ggmTable.GetAssetInfo(11); 71 | var buildSettingsBase = am.GetTypeInstance(ggmFile, buildSettings).GetBaseField(); 72 | var enabledVRDevices = buildSettingsBase.Get("enabledVRDevices").Get("Array"); 73 | var stringTemplate = enabledVRDevices.templateField.children[1]; 74 | var vrDevicesList = new[] {StringField("OpenVR", stringTemplate)}; 75 | enabledVRDevices.SetChildrenList(vrDevicesList); 76 | 77 | replacers.Add(new AssetsReplacerFromMemory(0, buildSettings.index, (int) buildSettings.curFileType, 0xffff, 78 | buildSettingsBase.WriteToByteArray())); 79 | 80 | using (var writer = new AssetsFileWriter(File.OpenWrite(gameManagersPath))) 81 | { 82 | ggmFile.Write(writer, 0, replacers, 0); 83 | } 84 | } 85 | 86 | private static AssetTypeValueField StringField(string str, AssetTypeTemplateField template) 87 | { 88 | return new AssetTypeValueField() 89 | { 90 | children = null, 91 | childrenCount = 0, 92 | templateField = template, 93 | value = new AssetTypeValue(EnumValueTypes.ValueType_String, str) 94 | }; 95 | } 96 | } -------------------------------------------------------------------------------- /BendyVRPatcher/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("BendyVRPatcher")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("BendyVRPatcher")] 12 | [assembly: AssemblyCopyright("Copyright © 2022")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("1CF5D773-2515-4684-879F-2645FDC8DB42")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /BendyVRPatcher/classdata.tpk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baggyg/BendyVR/cf09cf4ecb4c37cf12b45af70854c5562ba5216b/BendyVRPatcher/classdata.tpk -------------------------------------------------------------------------------- /BendyVRPatcher/obj/BendyVRPatcher.csproj.nuget.dgspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 1, 3 | "restore": { 4 | "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\BendyVRPatcher.csproj": {} 5 | }, 6 | "projects": { 7 | "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\BendyVRPatcher.csproj": { 8 | "version": "1.0.0", 9 | "restore": { 10 | "projectUniqueName": "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\BendyVRPatcher.csproj", 11 | "projectName": "BendyVRPatcher", 12 | "projectPath": "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\BendyVRPatcher.csproj", 13 | "packagesPath": "C:\\Users\\baggyg\\.nuget\\packages\\", 14 | "outputPath": "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\obj\\", 15 | "projectStyle": "PackageReference", 16 | "configFilePaths": [ 17 | "C:\\Users\\baggyg\\AppData\\Roaming\\NuGet\\NuGet.Config", 18 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 19 | ], 20 | "originalTargetFrameworks": [ 21 | "net35" 22 | ], 23 | "sources": { 24 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 25 | "https://api.nuget.org/v3/index.json": {}, 26 | "https://nuget.bepinex.dev/v3/index.json": {} 27 | }, 28 | "frameworks": { 29 | "net35": { 30 | "targetAlias": "net35", 31 | "projectReferences": {} 32 | } 33 | }, 34 | "warningProperties": { 35 | "warnAsError": [ 36 | "NU1605" 37 | ] 38 | } 39 | }, 40 | "frameworks": { 41 | "net35": { 42 | "targetAlias": "net35", 43 | "dependencies": { 44 | "AssetsTools.NET": { 45 | "target": "Package", 46 | "version": "[2.0.9, )" 47 | }, 48 | "Mono.Cecil": { 49 | "include": "Compile", 50 | "target": "Package", 51 | "version": "[0.10.4, )" 52 | } 53 | }, 54 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\6.0.307\\RuntimeIdentifierGraph.json" 55 | } 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /BendyVRPatcher/obj/BendyVRPatcher.csproj.nuget.g.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | NuGet 6 | $(MSBuildThisFileDirectory)project.assets.json 7 | $(UserProfile)\.nuget\packages\ 8 | C:\Users\baggyg\.nuget\packages\ 9 | PackageReference 10 | 6.2.1 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /BendyVRPatcher/obj/BendyVRPatcher.csproj.nuget.g.targets: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /BendyVRPatcher/obj/project.assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "targets": { 4 | ".NETFramework,Version=v3.5": { 5 | "AssetsTools.NET/2.0.9": { 6 | "type": "package", 7 | "dependencies": { 8 | "Mono.Cecil": "0.10.4" 9 | }, 10 | "compile": { 11 | "lib/net35/AssetsTools.NET.dll": {} 12 | }, 13 | "runtime": { 14 | "lib/net35/AssetsTools.NET.dll": {} 15 | } 16 | }, 17 | "Mono.Cecil/0.10.4": { 18 | "type": "package", 19 | "compile": { 20 | "lib/net35/Mono.Cecil.Mdb.dll": {}, 21 | "lib/net35/Mono.Cecil.Pdb.dll": {}, 22 | "lib/net35/Mono.Cecil.Rocks.dll": {}, 23 | "lib/net35/Mono.Cecil.dll": {} 24 | }, 25 | "runtime": { 26 | "lib/net35/_._": {} 27 | } 28 | } 29 | } 30 | }, 31 | "libraries": { 32 | "AssetsTools.NET/2.0.9": { 33 | "sha512": "gG87LmRhqRCc/rlu32Y+YsRYiDPPhGqSFDzzPVlHlsRVCh16M9qYNDwI/RcdGdpmGadnLgxBp+7bMflwZetgKw==", 34 | "type": "package", 35 | "path": "assetstools.net/2.0.9", 36 | "files": [ 37 | ".nupkg.metadata", 38 | ".signature.p7s", 39 | "assetstools.net.2.0.9.nupkg.sha512", 40 | "assetstools.net.nuspec", 41 | "icon.png", 42 | "lib/net35/AssetsTools.NET.dll", 43 | "lib/net40/AssetsTools.NET.dll", 44 | "lib/netstandard2.0/AssetsTools.NET.dll" 45 | ] 46 | }, 47 | "Mono.Cecil/0.10.4": { 48 | "sha512": "BHukPf7zfXu+akTcFEAWvU4x3hVMMIDC+ihGAl/+8OozrY0f/ajrpuaSUf2Q3Xvgsge5NryvOkjtyhV5TNXoSg==", 49 | "type": "package", 50 | "path": "mono.cecil/0.10.4", 51 | "files": [ 52 | ".nupkg.metadata", 53 | ".signature.p7s", 54 | "lib/net35/Mono.Cecil.Mdb.dll", 55 | "lib/net35/Mono.Cecil.Pdb.dll", 56 | "lib/net35/Mono.Cecil.Rocks.dll", 57 | "lib/net35/Mono.Cecil.dll", 58 | "lib/net40/Mono.Cecil.Mdb.dll", 59 | "lib/net40/Mono.Cecil.Pdb.dll", 60 | "lib/net40/Mono.Cecil.Rocks.dll", 61 | "lib/net40/Mono.Cecil.dll", 62 | "lib/netstandard1.3/Mono.Cecil.Mdb.dll", 63 | "lib/netstandard1.3/Mono.Cecil.Pdb.dll", 64 | "lib/netstandard1.3/Mono.Cecil.Rocks.dll", 65 | "lib/netstandard1.3/Mono.Cecil.dll", 66 | "mono.cecil.0.10.4.nupkg.sha512", 67 | "mono.cecil.nuspec" 68 | ] 69 | } 70 | }, 71 | "projectFileDependencyGroups": { 72 | ".NETFramework,Version=v3.5": [ 73 | "AssetsTools.NET >= 2.0.9", 74 | "Mono.Cecil >= 0.10.4" 75 | ] 76 | }, 77 | "packageFolders": { 78 | "C:\\Users\\baggyg\\.nuget\\packages\\": {} 79 | }, 80 | "project": { 81 | "version": "1.0.0", 82 | "restore": { 83 | "projectUniqueName": "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\BendyVRPatcher.csproj", 84 | "projectName": "BendyVRPatcher", 85 | "projectPath": "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\BendyVRPatcher.csproj", 86 | "packagesPath": "C:\\Users\\baggyg\\.nuget\\packages\\", 87 | "outputPath": "F:\\VRUnityModding\\BendyVR\\BendyVRPatcher\\obj\\", 88 | "projectStyle": "PackageReference", 89 | "configFilePaths": [ 90 | "C:\\Users\\baggyg\\AppData\\Roaming\\NuGet\\NuGet.Config", 91 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" 92 | ], 93 | "originalTargetFrameworks": [ 94 | "net35" 95 | ], 96 | "sources": { 97 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, 98 | "https://api.nuget.org/v3/index.json": {}, 99 | "https://nuget.bepinex.dev/v3/index.json": {} 100 | }, 101 | "frameworks": { 102 | "net35": { 103 | "targetAlias": "net35", 104 | "projectReferences": {} 105 | } 106 | }, 107 | "warningProperties": { 108 | "warnAsError": [ 109 | "NU1605" 110 | ] 111 | } 112 | }, 113 | "frameworks": { 114 | "net35": { 115 | "targetAlias": "net35", 116 | "dependencies": { 117 | "AssetsTools.NET": { 118 | "target": "Package", 119 | "version": "[2.0.9, )" 120 | }, 121 | "Mono.Cecil": { 122 | "include": "Compile", 123 | "target": "Package", 124 | "version": "[0.10.4, )" 125 | } 126 | }, 127 | "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\6.0.307\\RuntimeIdentifierGraph.json" 128 | } 129 | } 130 | } 131 | } -------------------------------------------------------------------------------- /BendyVRPatcher/obj/x64/Debug/BendyVRPatcher.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.RootNamespace = BendyVRPatcher 3 | build_property.ProjectDir = F:\VRUnityModding\BendyVR\BendyVRPatcher\ 4 | -------------------------------------------------------------------------------- /BendyVRPatcher/obj/x64/Release/BendyVRPatcher.GeneratedMSBuildEditorConfig.editorconfig: -------------------------------------------------------------------------------- 1 | is_global = true 2 | build_property.RootNamespace = BendyVRPatcher 3 | build_property.ProjectDir = F:\VRUnityModding\BendyVR\BendyVRPatcher\ 4 | -------------------------------------------------------------------------------- /BendyVRPatcher/obj/x64/Release/BendyVRPatcher.csproj.CopyComplete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baggyg/BendyVR/cf09cf4ecb4c37cf12b45af70854c5562ba5216b/BendyVRPatcher/obj/x64/Release/BendyVRPatcher.csproj.CopyComplete -------------------------------------------------------------------------------- /BendyVRPatcher/obj/x64/Release/BendyVRPatcher.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | F:\VRUnityModding\BendyVRInstall\Mod\BepInEx\patchers\BendyVRPatcher\classdata.tpk 2 | F:\VRUnityModding\BendyVRInstall\Mod\BepInEx\patchers\BendyVRPatcher\BendyVRPatcher.dll 3 | F:\VRUnityModding\BendyVR\BendyVRPatcher\obj\x64\Release\BendyVRPatcher.csproj.AssemblyReference.cache 4 | F:\VRUnityModding\BendyVR\BendyVRPatcher\obj\x64\Release\BendyVRPatcher.GeneratedMSBuildEditorConfig.editorconfig 5 | F:\VRUnityModding\BendyVR\BendyVRPatcher\obj\x64\Release\BendyVRPatcher.csproj.CoreCompileInputs.cache 6 | F:\VRUnityModding\BendyVR\BendyVRPatcher\obj\x64\Release\BendyVRPatcher.csproj.CopyComplete 7 | F:\VRUnityModding\BendyVR\BendyVRPatcher\obj\x64\Release\BendyVRPatcher.dll 8 | -------------------------------------------------------------------------------- /BendyVR_5/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /BendyVR_5/.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Uu]ser[Ss]ettings/ 12 | 13 | # MemoryCaptures can get excessive in size. 14 | # They also could contain extremely sensitive data 15 | /[Mm]emoryCaptures/ 16 | 17 | # Recordings can get excessive in size 18 | /[Rr]ecordings/ 19 | 20 | # Uncomment this line if you wish to ignore the asset store tools plugin 21 | # /[Aa]ssets/AssetStoreTools* 22 | 23 | # Autogenerated Jetbrains Rider plugin 24 | /[Aa]ssets/Plugins/Editor/JetBrains* 25 | 26 | # Visual Studio cache directory 27 | .vs/ 28 | 29 | # Gradle cache directory 30 | .gradle/ 31 | 32 | # Autogenerated VS/MD/Consulo solution and project files 33 | ExportedObj/ 34 | .consulo/ 35 | *.csproj 36 | *.unityproj 37 | *.sln 38 | *.suo 39 | *.tmp 40 | *.user 41 | *.userprefs 42 | *.pidb 43 | *.booproj 44 | *.svd 45 | *.pdb 46 | *.mdb 47 | *.opendb 48 | *.VC.db 49 | 50 | # Unity3D generated meta files 51 | *.pidb.meta 52 | *.pdb.meta 53 | *.mdb.meta 54 | 55 | # Unity3D generated file on crash reports 56 | sysinfo.txt 57 | 58 | # Builds 59 | *.apk 60 | *.aab 61 | *.unitypackage 62 | *.app 63 | 64 | # Crashlytics generated file 65 | crashlytics-build.properties 66 | 67 | # Packed Addressables 68 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* 69 | 70 | # Temporary auto-generated Android Assets 71 | /[Aa]ssets/[Ss]treamingAssets/aa.meta 72 | /[Aa]ssets/[Ss]treamingAssets/aa/* 73 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/AssetBundles/vrhands: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baggyg/BendyVR/cf09cf4ecb4c37cf12b45af70854c5562ba5216b/BendyVR_5/BendyVRAssets/AssetBundles/vrhands -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/AssetBundles/vrhands.manifest: -------------------------------------------------------------------------------- 1 | ManifestFileVersion: 0 2 | CRC: 2442546518 3 | Hashes: 4 | AssetFileHash: 5 | serializedVersion: 2 6 | Hash: e97711b33ca13c0ed35519ed21e54bac 7 | TypeTreeHash: 8 | serializedVersion: 2 9 | Hash: ce28056b625f1caf531d104f6545413d 10 | HashAppended: 0 11 | ClassTypes: 12 | - Class: 1 13 | Script: {instanceID: 0} 14 | - Class: 4 15 | Script: {instanceID: 0} 16 | - Class: 21 17 | Script: {instanceID: 0} 18 | - Class: 28 19 | Script: {instanceID: 0} 20 | - Class: 43 21 | Script: {instanceID: 0} 22 | - Class: 48 23 | Script: {instanceID: 0} 24 | - Class: 74 25 | Script: {instanceID: 0} 26 | - Class: 90 27 | Script: {instanceID: 0} 28 | - Class: 91 29 | Script: {instanceID: 0} 30 | - Class: 95 31 | Script: {instanceID: 0} 32 | - Class: 114 33 | Script: {fileID: 11500000, guid: e90911e410742a1498a167540c7865bf, type: 3} 34 | - Class: 114 35 | Script: {fileID: 11500000, guid: 00f6c0d7b5a00aa4a8d38a09a0480032, type: 3} 36 | - Class: 114 37 | Script: {fileID: 11500000, guid: e7418c7dd8f977d4e969202d3fa7e926, type: 3} 38 | - Class: 115 39 | Script: {instanceID: 0} 40 | - Class: 137 41 | Script: {instanceID: 0} 42 | - Class: 213 43 | Script: {instanceID: 0} 44 | Assets: 45 | - Assets/AssetBundles/VRHands/vr_glove_left.prefab 46 | - Assets/AssetBundles/VRHands/vr_glove_right_bkp.prefab 47 | - Assets/AssetBundles/VRHands/menu_bg.jpg 48 | - Assets/AssetBundles/VRHands/vr_glove_right.prefab 49 | - Assets/AssetBundles/VRHands/vr_glove_left_bkp.prefab 50 | Dependencies: [] 51 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/actions.json: -------------------------------------------------------------------------------- 1 | { 2 | "actions": [ 3 | { 4 | "name": "/actions/default/in/PoseLeftHand", 5 | "type": "pose" 6 | }, 7 | { 8 | "name": "/actions/default/in/PoseRightHand", 9 | "type": "pose" 10 | }, 11 | { 12 | "name": "/actions/default/in/SkeletonLeftHand", 13 | "type": "skeleton", 14 | "skeleton": "/skeleton/hand/left" 15 | }, 16 | { 17 | "name": "/actions/default/in/SkeletonRightHand", 18 | "type": "skeleton", 19 | "skeleton": "/skeleton/hand/right" 20 | }, 21 | { 22 | "name": "/actions/default/in/HeadsetOnHead", 23 | "type": "boolean", 24 | "requirement": "optional" 25 | }, 26 | { 27 | "name": "/actions/default/out/Haptic", 28 | "type": "vibration" 29 | }, 30 | { 31 | "name": "/actions/DominantHand/in/SeeingTool", 32 | "type": "boolean" 33 | }, 34 | { 35 | "name": "/actions/DominantHand/in/Weapon", 36 | "type": "boolean" 37 | }, 38 | { 39 | "name": "/actions/NonDominantHand/in/Pause", 40 | "type": "boolean" 41 | }, 42 | { 43 | "name": "/actions/NonDominantHand/in/Interact", 44 | "type": "boolean" 45 | }, 46 | { 47 | "name": "/actions/MovementHand/in/Move", 48 | "type": "vector2" 49 | }, 50 | { 51 | "name": "/actions/MovementHand/in/Run", 52 | "type": "boolean" 53 | }, 54 | { 55 | "name": "/actions/RotationHand/in/Rotate", 56 | "type": "vector2" 57 | }, 58 | { 59 | "name": "/actions/RotationHand/in/SnapTurnLeft", 60 | "type": "boolean" 61 | }, 62 | { 63 | "name": "/actions/RotationHand/in/Jump", 64 | "type": "boolean" 65 | }, 66 | { 67 | "name": "/actions/RotationHand/in/UiUp", 68 | "type": "boolean" 69 | }, 70 | { 71 | "name": "/actions/RotationHand/in/UiDown", 72 | "type": "boolean" 73 | }, 74 | { 75 | "name": "/actions/RotationHand/in/Previous", 76 | "type": "boolean" 77 | }, 78 | { 79 | "name": "/actions/RotationHand/in/Next", 80 | "type": "boolean" 81 | }, 82 | { 83 | "name": "/actions/RotationHand/in/SnapTurnRight", 84 | "type": "boolean" 85 | }, 86 | { 87 | "name": "/actions/RotationHand/in/Cancel", 88 | "type": "boolean" 89 | } 90 | ], 91 | "action_sets": [ 92 | { 93 | "name": "/actions/default", 94 | "usage": "leftright" 95 | }, 96 | { 97 | "name": "/actions/DominantHand", 98 | "usage": "single" 99 | }, 100 | { 101 | "name": "/actions/NonDominantHand", 102 | "usage": "single" 103 | }, 104 | { 105 | "name": "/actions/MovementHand", 106 | "usage": "single" 107 | }, 108 | { 109 | "name": "/actions/RotationHand", 110 | "usage": "single" 111 | } 112 | ], 113 | "default_bindings": [ 114 | { 115 | "controller_type": "vive_controller", 116 | "binding_url": "bindings_vive_controller.json" 117 | }, 118 | { 119 | "controller_type": "oculus_touch", 120 | "binding_url": "bindings_oculus_touch.json" 121 | }, 122 | { 123 | "controller_type": "knuckles", 124 | "binding_url": "bindings_knuckles.json" 125 | }, 126 | { 127 | "controller_type": "holographic_controller", 128 | "binding_url": "bindings_holographic_controller.json" 129 | }, 130 | { 131 | "controller_type": "vive_cosmos_controller", 132 | "binding_url": "bindings_vive_cosmos_controller.json" 133 | }, 134 | { 135 | "controller_type": "vive_cosmos", 136 | "binding_url": "binding_vive_cosmos.json" 137 | }, 138 | { 139 | "controller_type": "vive", 140 | "binding_url": "binding_vive.json" 141 | }, 142 | { 143 | "controller_type": "indexhmd", 144 | "binding_url": "binding_index_hmd.json" 145 | }, 146 | { 147 | "controller_type": "vive_pro", 148 | "binding_url": "binding_vive_pro.json" 149 | }, 150 | { 151 | "controller_type": "rift", 152 | "binding_url": "binding_rift.json" 153 | }, 154 | { 155 | "controller_type": "holographic_hmd", 156 | "binding_url": "binding_holographic_hmd.json" 157 | }, 158 | { 159 | "controller_type": "vive_tracker_camera", 160 | "binding_url": "binding_vive_tracker_camera.json" 161 | } 162 | ], 163 | "localization": [ 164 | { 165 | "language_tag": "en_US", 166 | "/actions/default/in/HeadsetOnHead": "Headset on head (proximity sensor)", 167 | "/actions/default/in/SkeletonLeftHand": "Skeleton (Left)", 168 | "/actions/default/in/SkeletonRightHand": "Skeleton (Right)", 169 | "/actions/default/out/Haptic": "Haptic", 170 | "/actions/RotationHand/in/Rotate": "Rotate", 171 | "/actions/RotationHand/in/SnapTurnLeft": "Snap Turn Left", 172 | "/actions/RotationHand/in/Jump": "Jump", 173 | "/actions/RotationHand/in/UiUp": "UI Up", 174 | "/actions/RotationHand/in/UiDown": "UI Down", 175 | "/actions/RotationHand/in/Previous": "Previous", 176 | "/actions/RotationHand/in/Next": "Next", 177 | "/actions/MovementHand/in/Move": "Move", 178 | "/actions/MovementHand/in/Run": "Run", 179 | "/actions/DominantHand/in/Weapon": "Weapon", 180 | "/actions/RotationHand/in/SnapTurnRight": "Snap Turn Right", 181 | "/actions/default/in/PoseRightHand": "Right Hand Pose", 182 | "/actions/NonDominantHand/in/Pause": "Pause Game", 183 | "/actions/RotationHand/in/Cancel": "Cancel (UI)", 184 | "/actions/default/in/PoseLeftHand": "Pose Left Hand", 185 | "/actions/DominantHand/in/SeeingTool": "SeeingTool", 186 | "/actions/NonDominantHand/in/Interact": "Interact" 187 | } 188 | ] 189 | } -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_holographic_hmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias_info" : {}, 3 | "bindings" : { 4 | "/actions/default" : { 5 | "chords" : [], 6 | "haptics" : [], 7 | "poses" : [], 8 | "skeleton" : [], 9 | "sources" : [ 10 | { 11 | "inputs" : { 12 | "click" : { 13 | "output" : "/actions/default/in/headsetonhead" 14 | } 15 | }, 16 | "mode" : "button", 17 | "path" : "/user/head/proximity" 18 | } 19 | ] 20 | } 21 | }, 22 | "controller_type" : "holographic_hmd", 23 | "description" : "", 24 | "name" : "holographic_hmd defaults", 25 | "options" : {}, 26 | "simulated_actions" : [] 27 | } 28 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_index_hmd.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias_info": {}, 3 | "bindings": { 4 | "/actions/default": { 5 | "chords": [], 6 | "haptics": [], 7 | "poses": [], 8 | "skeleton": [], 9 | "sources": [ 10 | { 11 | "inputs": { 12 | "click": { 13 | "output": "/actions/default/in/headsetonhead" 14 | } 15 | }, 16 | "mode": "button", 17 | "path": "/user/head/proximity" 18 | } 19 | ] 20 | } 21 | }, 22 | "controller_type": "indexhmd", 23 | "description": "", 24 | "name": "index hmd defaults", 25 | "options": {}, 26 | "simulated_actions": [] 27 | } 28 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_rift.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias_info" : {}, 3 | "bindings" : { 4 | "/actions/default" : { 5 | "chords" : [], 6 | "haptics" : [], 7 | "poses" : [], 8 | "skeleton" : [], 9 | "sources" : [ 10 | { 11 | "inputs" : { 12 | "click" : { 13 | "output" : "/actions/default/in/headsetonhead" 14 | } 15 | }, 16 | "mode" : "button", 17 | "path" : "/user/head/proximity" 18 | } 19 | ] 20 | } 21 | }, 22 | "controller_type" : "rift", 23 | "description" : "", 24 | "name" : "rift defaults", 25 | "options" : {}, 26 | "simulated_actions" : [] 27 | } 28 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_vive.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias_info" : {}, 3 | "bindings" : { 4 | "/actions/default" : { 5 | "chords" : [], 6 | "haptics" : [], 7 | "poses" : [], 8 | "skeleton" : [], 9 | "sources" : [ 10 | { 11 | "inputs" : { 12 | "click" : { 13 | "output" : "/actions/default/in/headsetonhead" 14 | } 15 | }, 16 | "mode" : "button", 17 | "path" : "/user/head/proximity" 18 | } 19 | ] 20 | } 21 | }, 22 | "controller_type" : "vive", 23 | "description" : "", 24 | "name" : "vive defaults", 25 | "options" : {}, 26 | "simulated_actions" : [] 27 | } 28 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_vive_cosmos.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias_info": {}, 3 | "bindings": { 4 | "/actions/default": { 5 | "chords": [], 6 | "haptics": [], 7 | "poses": [], 8 | "skeleton": [], 9 | "sources": [ 10 | { 11 | "inputs": { 12 | "click": { 13 | "output": "/actions/default/in/headsetonhead" 14 | } 15 | }, 16 | "mode": "button", 17 | "path": "/user/head/proximity" 18 | } 19 | ] 20 | } 21 | }, 22 | "controller_type": "vive_cosmos", 23 | "description": "", 24 | "name": "vive cosmos hmd defaults", 25 | "options": {}, 26 | "simulated_actions": [] 27 | } 28 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_vive_pro.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias_info" : {}, 3 | "bindings" : { 4 | "/actions/default" : { 5 | "chords" : [], 6 | "haptics" : [], 7 | "poses" : [], 8 | "skeleton" : [], 9 | "sources" : [ 10 | { 11 | "inputs" : { 12 | "click" : { 13 | "output" : "/actions/default/in/headsetonhead" 14 | } 15 | }, 16 | "mode" : "button", 17 | "path" : "/user/head/proximity" 18 | } 19 | ] 20 | } 21 | }, 22 | "controller_type" : "vive_pro", 23 | "description" : "", 24 | "name" : "vive_pro defaults", 25 | "options" : {}, 26 | "simulated_actions" : [] 27 | } 28 | -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/binding_vive_tracker_camera.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/mixedreality": { 4 | "chords": [], 5 | "poses": [], 6 | "haptics": [], 7 | "sources": [], 8 | "skeleton": [] 9 | } 10 | }, 11 | "controller_type": "vive_tracker_camera", 12 | "description": "", 13 | "name": "tracker_forcamera" 14 | } -------------------------------------------------------------------------------- /BendyVR_5/BendyVRAssets/Bindings/bindings_vive_cosmos_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "bindings": { 3 | "/actions/buggy": { 4 | "chords": [], 5 | "poses": [], 6 | "haptics": [], 7 | "sources": [], 8 | "skeleton": [] 9 | }, 10 | "/actions/default": { 11 | "chords": [], 12 | "poses": [], 13 | "haptics": [ 14 | { 15 | "output": "/actions/default/out/haptic", 16 | "path": "/user/hand/left/output/haptic" 17 | }, 18 | { 19 | "output": "/actions/default/out/haptic", 20 | "path": "/user/hand/right/output/haptic" 21 | } 22 | ], 23 | "sources": [], 24 | "skeleton": [ 25 | { 26 | "output": "/actions/default/in/skeletonlefthand", 27 | "path": "/user/hand/left/input/skeleton/left" 28 | }, 29 | { 30 | "output": "/actions/default/in/skeletonrighthand", 31 | "path": "/user/hand/right/input/skeleton/right" 32 | } 33 | ] 34 | }, 35 | "/actions/platformer": { 36 | "chords": [], 37 | "poses": [], 38 | "haptics": [], 39 | "sources": [], 40 | "skeleton": [] 41 | } 42 | }, 43 | "controller_type": "vive_cosmos_controller", 44 | "description": "", 45 | "name": "vive_cosmos_controller" 46 | } -------------------------------------------------------------------------------- /BendyVR_5/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Grant Bagwell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/BepInEx/config/BepInEx.cfg: -------------------------------------------------------------------------------- 1 | [Caching] 2 | 3 | ## Enable/disable assembly metadata cache 4 | ## Enabling this will speed up discovery of plugins and patchers by caching the metadata of all types BepInEx discovers. 5 | # Setting type: Boolean 6 | # Default value: true 7 | EnableAssemblyCache = true 8 | 9 | [Chainloader] 10 | 11 | ## If enabled, hides BepInEx Manager GameObject from Unity. 12 | ## This can fix loading issues in some games that attempt to prevent BepInEx from being loaded. 13 | ## Use this only if you know what this option means, as it can affect functionality of some older plugins. 14 | ## 15 | # Setting type: Boolean 16 | # Default value: false 17 | HideManagerGameObject = false 18 | 19 | [Harmony.Logger] 20 | 21 | ## Specifies which Harmony log channels to listen to. 22 | ## NOTE: IL channel dumps the whole patch methods, use only when needed! 23 | # Setting type: LogChannel 24 | # Default value: Warn, Error 25 | # Acceptable values: None, Info, IL, Warn, Error, Debug, All 26 | # Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning) 27 | LogChannels = Warn, Error 28 | 29 | [Logging] 30 | 31 | ## Enables showing unity log messages in the BepInEx logging system. 32 | # Setting type: Boolean 33 | # Default value: true 34 | UnityLogListening = true 35 | 36 | ## If enabled, writes Standard Output messages to Unity log 37 | ## NOTE: By default, Unity does so automatically. Only use this option if no console messages are visible in Unity log 38 | ## 39 | # Setting type: Boolean 40 | # Default value: false 41 | LogConsoleToUnityLog = false 42 | 43 | [Logging.Console] 44 | 45 | ## Enables showing a console for log output. 46 | # Setting type: Boolean 47 | # Default value: false 48 | Enabled = true 49 | 50 | ## If enabled, will prevent closing the console (either by deleting the close button or in other platform-specific way). 51 | # Setting type: Boolean 52 | # Default value: false 53 | PreventClose = false 54 | 55 | ## If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding. 56 | # Setting type: Boolean 57 | # Default value: false 58 | ShiftJisEncoding = false 59 | 60 | ## Hints console manager on what handle to assign as StandardOut. Possible values: 61 | ## Auto - lets BepInEx decide how to redirect console output 62 | ## ConsoleOut - prefer redirecting to console output; if possible, closes original standard output 63 | ## StandardOut - prefer redirecting to standard output; if possible, closes console out 64 | ## 65 | # Setting type: ConsoleOutRedirectType 66 | # Default value: Auto 67 | # Acceptable values: Auto, ConsoleOut, StandardOut 68 | StandardOutType = Auto 69 | 70 | ## Which log levels to show in the console output. 71 | # Setting type: LogLevel 72 | # Default value: Fatal, Error, Warning, Message, Info 73 | # Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All 74 | # Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning) 75 | LogLevels = Fatal, Error, Warning, Message, Info 76 | 77 | [Logging.Disk] 78 | 79 | ## Include unity log messages in log file output. 80 | # Setting type: Boolean 81 | # Default value: false 82 | WriteUnityLog = false 83 | 84 | ## Appends to the log file instead of overwriting, on game startup. 85 | # Setting type: Boolean 86 | # Default value: false 87 | AppendLog = false 88 | 89 | ## Enables writing log messages to disk. 90 | # Setting type: Boolean 91 | # Default value: true 92 | Enabled = true 93 | 94 | ## Which log leves are saved to the disk log output. 95 | # Setting type: LogLevel 96 | # Default value: Fatal, Error, Warning, Message, Info 97 | # Acceptable values: None, Fatal, Error, Warning, Message, Info, Debug, All 98 | # Multiple values can be set at the same time by separating them with , (e.g. Debug, Warning) 99 | LogLevels = Fatal, Error, Warning, Message, Info 100 | 101 | [Preloader] 102 | 103 | ## Enables or disables runtime patches. 104 | ## This should always be true, unless you cannot start the game due to a Harmony related issue (such as running .NET Standard runtime) or you know what you're doing. 105 | # Setting type: Boolean 106 | # Default value: true 107 | ApplyRuntimePatches = true 108 | 109 | ## Specifies which MonoMod backend to use for Harmony patches. Auto uses the best available backend. 110 | ## This setting should only be used for development purposes (e.g. debugging in dnSpy). Other code might override this setting. 111 | # Setting type: MonoModBackend 112 | # Default value: auto 113 | # Acceptable values: auto, dynamicmethod, methodbuilder, cecil 114 | HarmonyBackend = auto 115 | 116 | ## If enabled, BepInEx will save patched assemblies into BepInEx/DumpedAssemblies. 117 | ## This can be used by developers to inspect and debug preloader patchers. 118 | # Setting type: Boolean 119 | # Default value: false 120 | DumpAssemblies = false 121 | 122 | ## If enabled, BepInEx will load patched assemblies from BepInEx/DumpedAssemblies instead of memory. 123 | ## This can be used to be able to load patched assemblies into debuggers like dnSpy. 124 | ## If set to true, will override DumpAssemblies. 125 | # Setting type: Boolean 126 | # Default value: false 127 | LoadDumpedAssemblies = false 128 | 129 | ## If enabled, BepInEx will call Debugger.Break() once before loading patched assemblies. 130 | ## This can be used with debuggers like dnSpy to install breakpoints into patched assemblies before they are loaded. 131 | # Setting type: Boolean 132 | # Default value: false 133 | BreakBeforeLoadAssemblies = false 134 | 135 | [Preloader.Entrypoint] 136 | 137 | ## The local filename of the assembly to target. 138 | # Setting type: String 139 | # Default value: UnityEngine.CoreModule.dll 140 | Assembly = UnityEngine.CoreModule.dll 141 | 142 | ## The name of the type in the entrypoint assembly to search for the entrypoint method. 143 | # Setting type: String 144 | # Default value: Application 145 | Type = Application 146 | 147 | ## The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from. 148 | # Setting type: String 149 | # Default value: .cctor 150 | Method = .cctor 151 | 152 | -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/BepInEx/core/BepInEx.Harmony.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BepInEx.Harmony 5 | 6 | 7 | 8 | 9 | Specifies the indices of parameters that are ByRef. 10 | 11 | 12 | 13 | 14 | The indices of parameters that are ByRef. 15 | 16 | 17 | 18 | The indices of parameters that are ByRef. 19 | 20 | 21 | 22 | An extension class for Harmony based operations. 23 | 24 | 25 | 26 | 27 | Applies all patches specified in the type. 28 | 29 | The HarmonyInstance to use. 30 | The type to scan. 31 | 32 | 33 | 34 | A wrapper for Harmony based operations. 35 | 36 | 37 | 38 | 39 | Applies all patches specified in the type. 40 | 41 | The type to scan. 42 | The HarmonyInstance to use. 43 | 44 | 45 | 46 | Applies all patches specified in the type. 47 | 48 | The type to scan. 49 | The ID for the Harmony instance to create, which will be used. 50 | 51 | 52 | 53 | Applies all patches specified in the assembly. 54 | 55 | The assembly to scan. 56 | The HarmonyInstance to use. 57 | 58 | 59 | 60 | Applies all patches specified in the assembly. 61 | 62 | The assembly to scan. 63 | The ID for the Harmony instance to create, which will be used. 64 | 65 | 66 | 67 | Applies all patches specified in the calling assembly. 68 | 69 | The Harmony instance to use. 70 | 71 | 72 | 73 | Applies all patches specified in the calling assembly. 74 | 75 | The ID for the Harmony instance to create, which will be used. 76 | 77 | 78 | 79 | Returns an instruction to call the specified delegate. 80 | 81 | The delegate type to emit. 82 | The delegate to emit. 83 | The instruction to 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/BepInEx/core/BepInEx.Preloader.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | BepInEx.Preloader 5 | 6 | 7 | 8 | 9 | Doorstop environment variables, passed into the BepInEx preloader. 10 | https://github.com/NeighTools/UnityDoorstop/wiki#environment-variables 11 | 12 | 13 | 14 | 15 | Path to the assembly that was invoked via Doorstop. Contains the same value as in "targetAssembly" configuration option in the config file. 16 | 17 | 18 | 19 | 20 | Full path to the game's "Managed" folder that contains all the game's managed assemblies 21 | 22 | 23 | 24 | 25 | Full path to the game executable currently running. 26 | 27 | 28 | 29 | 30 | Array of paths where Mono searches DLLs from before assembly resolvers are invoked. 31 | 32 | 33 | 34 | 35 | Delegate used in patching assemblies. 36 | 37 | The assembly that is being patched. 38 | 39 | 40 | 41 | Worker class which is used for loading and patching entire folders of assemblies, or alternatively patching and 42 | loading assemblies one at a time. 43 | 44 | 45 | 46 | 47 | List of all patcher plugins to be applied 48 | 49 | 50 | 51 | 52 | Adds a single assembly patcher to the pool of applicable patches. 53 | 54 | Patcher to apply. 55 | 56 | 57 | 58 | Adds all patchers from all managed assemblies specified in a directory. 59 | 60 | Directory to search patcher DLLs from. 61 | 62 | 63 | 64 | Releases all patchers to let them be collected by GC. 65 | 66 | 67 | 68 | 69 | Applies patchers to all assemblies in the given directory and loads patched assemblies into memory. 70 | 71 | Directories to load CLR assemblies from in their search order. 72 | 73 | 74 | 75 | Loads an individual assembly definition into the CLR. 76 | 77 | The assembly to load. 78 | File name of the assembly being loaded. 79 | 80 | 81 | 82 | A single assembly patcher. 83 | 84 | 85 | 86 | 87 | Target assemblies to patch. 88 | 89 | 90 | 91 | 92 | Initializer method that is run before any patching occurs. 93 | 94 | 95 | 96 | 97 | Finalizer method that is run after all patching is done. 98 | 99 | 100 | 101 | 102 | The main patcher method that is called on every DLL defined in . 103 | 104 | 105 | 106 | 107 | Type name of the patcher. 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | The main entrypoint of BepInEx, called from Doorstop. 119 | 120 | 121 | 122 | 123 | Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes. 124 | 125 | 126 | 127 | 128 | This exists because the Mono implementation of is/was broken, and would call Write directly instead of calling TraceEvent. 129 | 130 | 131 | 132 | 133 | The main entrypoint of BepInEx, and initializes all patchers and the chainloader. 134 | 135 | 136 | 137 | 138 | The log writer that is specific to the preloader. 139 | 140 | 141 | 142 | 143 | Inserts BepInEx's own chainloader entrypoint into UnityEngine. 144 | 145 | The assembly that will be attempted to be patched. 146 | 147 | 148 | 149 | Allocates a console window for use by BepInEx safely. 150 | 151 | 152 | 153 | 154 | Log listener that listens to logs during preloading time and buffers messages for output in Unity logs later. 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/CopyToGame/Bendy and the Ink Machine_Data/Plugins/openvr_mod.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "fsr": { 3 | // enable image upscaling through AMD's FSR or NVIDIA's NIS 4 | "enabled": true, 5 | 6 | // if enabled, uses NVIDIA's Image Scaling instead of the default 7 | // AMD FidelityFX SuperResolution. Both algorithms work similarly, but produce 8 | // somewhat different results. You may want to experiment switching between the 9 | // two to determine which one you like better for a particular game. 10 | "useNIS": false, 11 | 12 | // Per-dimension render scale. If <1, will lower the game's render resolution 13 | // accordingly and afterwards upscale to the "native" resolution set in SteamVR. 14 | // If >1, the game will render at its "native" resolution, and afterwards the 15 | // image is upscaled to a higher resolution as per the given value. 16 | // If =1, effectively disables upsampling, but you'll still get the sharpening stage. 17 | // AMD presets: 18 | // Ultra Quality => 0.77 19 | // Quality => 0.67 20 | // Balanced => 0.59 21 | // Performance => 0.50 22 | "renderScale": 0.77, 23 | 24 | // tune sharpness, values range from 0 to 1 25 | "sharpness": 0.5, 26 | 27 | // Only apply FSR/NIS to the given radius around the center of the image. 28 | // Anything outside this radius is upscaled by simple bilinear filtering, 29 | // which is cheaper and thus saves a bit of performance. Due to the design 30 | // of current HMD lenses, you can experiment with fairly small radii and may 31 | // still not see a noticeable difference. 32 | // Sensible values probably lie somewhere between [0.2, 1.0]. However, note 33 | // that, since the image is not spheric, even a value of 1.0 technically still 34 | // skips some pixels in the corner of the image, so if you want to completely 35 | // disable this optimization, you can choose a value of 2. 36 | // IMPORTANT: if you face issues like the view appearing offset or mismatched 37 | // between the eyes, turn this optimization off by setting the value to 2.0 38 | "radius": 0.5, 39 | 40 | // if enabled, applies a negative LOD bias to texture MIP levels 41 | // should theoretically improve texture detail in the upscaled image 42 | // IMPORTANT: if you experience issues with rendering like disappearing 43 | // textures or strange patterns in the rendering, try turning this off 44 | // by setting the value to false. 45 | "applyMIPBias": true, 46 | 47 | // If enabled, will visualize the radius to which FSR/NIS is applied. 48 | // Will also periodically log the GPU cost for applying FSR/NIS in the 49 | // current configuration. 50 | "debugMode": false 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/CopyToGame/doorstop_config.ini: -------------------------------------------------------------------------------- 1 | [UnityDoorstop] 2 | enabled=true 3 | targetAssembly=F:\VRUnityModding\BendyVRInstall\Mod\BepInEx\core\BepInEx.Preloader.dll 4 | ignoreDisableSwitch=true -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baggyg/BendyVR/cf09cf4ecb4c37cf12b45af70854c5562ba5216b/BendyVR_5/ModFiles/icon.png -------------------------------------------------------------------------------- /BendyVR_5/ModFiles/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "bendy-vr", 3 | "modTitle": "Bendy VR", 4 | "gameTitle": "Bendy and the Ink Machine", 5 | "providers": [ 6 | { 7 | "providerId": "steam", 8 | "gameIdentifier": "Bendy and the Ink Machine", 9 | "requireAdmin": false, 10 | "gameExe": "Bendy and the Ink Machine.exe" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /BendyVR_5/NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BendyVR_5/src/Assets/VrAssetLoader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using BendyVR_5.Helpers; 4 | using BendyVR_5.Settings; 5 | using BepInEx; 6 | using UnityEngine; 7 | 8 | namespace BendyVR_5.Assets; 9 | 10 | public static class VrAssetLoader 11 | { 12 | private const string assetsDir = "BendyVRAssets/AssetBundles/"; 13 | public static readonly Dictionary LivShaders = new(); 14 | 15 | public static Shader TMProShader { get; private set; } 16 | public static Shader FadeShader { get; private set; } 17 | public static GameObject VrSettingsMenuPrefab { get; private set; } 18 | public static GameObject LeftHandPrefab { get; private set; } 19 | public static GameObject RightHandPrefab { get; private set; } 20 | public static GameObject TeleportTargetPrefab { get; private set; } 21 | public static Sprite MenuBG { get; private set; } 22 | 23 | 24 | public static void LoadAssets() 25 | { 26 | Logs.WriteInfo("Loading VRHands Assets"); 27 | var vrBundle = LoadBundle("vrhands"); 28 | if (VrSettings.ShowLegacySteamVRHands.Value == true) 29 | { 30 | LeftHandPrefab = vrBundle.LoadAsset("vr_glove_left_bkp"); 31 | RightHandPrefab = vrBundle.LoadAsset("vr_glove_right_bkp"); 32 | } 33 | else 34 | { 35 | LeftHandPrefab = vrBundle.LoadAsset("vr_glove_left"); 36 | RightHandPrefab = vrBundle.LoadAsset("vr_glove_right"); 37 | } 38 | 39 | MenuBG = vrBundle.LoadAsset("menu_bg"); 40 | } 41 | 42 | private static AssetBundle LoadBundle(string assetName) 43 | { 44 | var bundle = AssetBundle.LoadFromFile(Path.Combine(Paths.PluginPath, Path.Combine(assetsDir, assetName))); 45 | if (bundle != null) return bundle; 46 | Logs.WriteError($"Failed to load AssetBundle {assetName}"); 47 | return null; 48 | } 49 | } -------------------------------------------------------------------------------- /BendyVR_5/src/BendyVRBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace BendyVR_5.src; 6 | 7 | public abstract class BendyVRBehavior : MonoBehaviour 8 | { 9 | private static readonly Dictionary> typeInstanceMap = new(); 10 | 11 | protected virtual void Awake() 12 | { 13 | if (typeInstanceMap.ContainsKey(GetType())) 14 | typeInstanceMap[GetType()].Add(this); 15 | else 16 | typeInstanceMap[GetType()] = new List { this }; 17 | } 18 | 19 | protected virtual void OnDestroy() 20 | { 21 | typeInstanceMap.TryGetValue(GetType(), out var instance); 22 | 23 | instance?.Remove(this); 24 | } 25 | 26 | protected abstract void VeryLateUpdate(); 27 | 28 | public static void InvokeVeryLateUpdate() where TBehavior : BendyVRBehavior 29 | { 30 | typeInstanceMap.TryGetValue(typeof(TBehavior), out var instances); 31 | if (instances == null) return; 32 | foreach (var instance in instances) instance.InvokeVeryLateUpdateIfEnabled(); 33 | } 34 | 35 | private void InvokeVeryLateUpdateIfEnabled() 36 | { 37 | if (!enabled) return; 38 | VeryLateUpdate(); 39 | } 40 | } -------------------------------------------------------------------------------- /BendyVR_5/src/BendyVRMod.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Assets; 2 | using BendyVR_5.Settings; 3 | using BepInEx; 4 | using BepInEx.Configuration; 5 | using BepInEx.Logging; 6 | using HarmonyLib; 7 | using System.Linq; 8 | using System.Reflection; 9 | using UnityEngine; 10 | using Valve.VR; 11 | 12 | namespace BendyVR_5.src; 13 | 14 | [BepInPlugin("org.baggyg.vrplugins.bendyvr", "BendyVR", "1.1.0")] 15 | [BepInProcess("Bendy and the Ink Machine.exe")] 16 | 17 | // A soft dependency. Loading won't be skipped if it's missing. 18 | //[BepInDependency("com.bepinex.plugin.somedependency", BepInDependency.DependencyFlags.SoftDependency)] 19 | // A hard dependency. Loading will be skipped (and an error shown) if the dependency is missing. 20 | //[BepInDependency("com.bepinex.plugin.importantdependency", BepInDependency.DependencyFlags.HardDependency)] 21 | // If flags are not specified, the dependency is **hard** by default 22 | //[BepInDependency("com.bepinex.plugin.anotherimportantone")] 23 | // Depends on com.bepinex.plugin.versioned version 1.2.x 24 | //[BepInDependency("com.bepinex.plugin.versioned", "~1.2")] 25 | 26 | // If some.undesirable.plugin is installed, this plugin is skipped 27 | //[BepInIncompatibility("some.undesirable.plugin")] 28 | public class BendyVRPlugin : BaseUnityPlugin 29 | { 30 | internal static ManualLogSource logBendyVR; 31 | private ConfigEntry configEnableMod; 32 | 33 | private void Awake() 34 | { 35 | // Plugin startup logic 36 | 37 | //LOGGING 38 | logBendyVR = new ManualLogSource("BendyVRLog"); // The source name is shown in BepInEx log 39 | BepInEx.Logging.Logger.Sources.Add(logBendyVR); 40 | logBendyVR.LogInfo($"Plugin {PluginInfo.PLUGIN_GUID} is loaded!"); 41 | 42 | //logBendyVR.LogWarning("This is a warning - Auto Installed"); 43 | //logBendyVR.LogError("This is an error - No Time to Do it!"); 44 | 45 | //CONFIG SETTINGS 46 | //HARMONY PATCHING OF METHODS 47 | VrSettings.SetUp(Config); 48 | Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly()); 49 | VrAssetLoader.LoadAssets(); 50 | InitSteamVR(); 51 | 52 | // Remove the source to free resources 53 | //BepInEx.Logging.Logger.Sources.Remove(logBendyVR); 54 | } 55 | 56 | private static void InitSteamVR() 57 | { 58 | logBendyVR.LogInfo("Initalising SteamVR"); 59 | SteamVR_Actions.PreInitialize(); 60 | SteamVR.Initialize(true); //Force Unity VR Mode via true 61 | SteamVR_Settings.instance.pauseGameWhenDashboardVisible = true; 62 | logBendyVR.LogInfo("SteamVR Initialised"); 63 | } 64 | 65 | /*private void SetupUI() 66 | { 67 | var canvases = GameObject.FindObjectsOfType().Where(canvas => canvas.renderMode == RenderMode.ScreenSpaceOverlay); 68 | canvases.Do(canvas => 69 | { 70 | canvas.worldCamera = Camera.main; 71 | canvas.renderMode = RenderMode.WorldSpace; 72 | canvas.transform.SetParent(Camera.main.transform, false); 73 | canvas.transform.localPosition = Vector3.forward * 0.5f; 74 | canvas.transform.localScale = Vector3.one * 0.0004f; 75 | 76 | }); 77 | }*/ 78 | } 79 | -------------------------------------------------------------------------------- /BendyVR_5/src/BendyVRPatch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using BendyVR_5.Stage; 6 | 7 | 8 | namespace BendyVR_5.src; 9 | 10 | public abstract class BendyVRPatch 11 | { 12 | protected static VrCore StageInstance; 13 | 14 | public static void SetStage(VrCore vrStage) 15 | { 16 | StageInstance = vrStage; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BendyVR_5/src/Chapters/Patches/CH1Fixes.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using BendyVR_5.UI; 4 | using DG.Tweening; 5 | using HarmonyLib; 6 | using TMG.Controls; 7 | using TMG.Core; 8 | using UnityEngine; 9 | using UnityEngine.VR; 10 | using UnityEngine.XR; 11 | 12 | 13 | namespace BendyVR_5.Chapters.Patches; 14 | 15 | [HarmonyPatch] 16 | public class CH1Fixes : BendyVRPatch 17 | { 18 | /* 19 | [HarmonyPrefix] 20 | [HarmonyPatch(typeof(CH1TheatreController), nameof(CH1TheatreController.DOFlooding))] 21 | private static bool DODifferentFlooding(CH1TheatreController __instance, ref Sequence __result) 22 | { 23 | Sequence sequence = DOTween.Sequence(); 24 | float num = 0f; 25 | float num2 = 4f; 26 | __instance.m_RaisingInk.tag = "Ink"; 27 | //sequence.Insert(num, __instance.m_InkRenderer.material.DOFloat(1f, "_Cutout", num2).SetEase(Ease.InQuad)); 28 | __instance.m_InkRenderer.material.shader. 29 | sequence.Insert(num, __instance.m_InkRenderer.material.DOFloat(1f, "_Cutout", 0.0f).SetEase(Ease.InQuad)); 30 | num += num2; 31 | num2 += num2 / 2f; 32 | sequence.Insert(num, __instance.m_RaisingInk.DOLocalMoveY(__instance.m_RaisingInk.localPosition.y + 1f, num2).SetEase(Ease.InOutQuad)); 33 | sequence.InsertCallback(num + num2 / 8f, delegate 34 | { 35 | __instance.m_RaisingInk.tag = "DeepInk"; 36 | }); 37 | __result = sequence; 38 | return false; 39 | }*/ 40 | 41 | [HarmonyPrefix] 42 | [HarmonyPatch(typeof(CH1BendyFinaleController), nameof(CH1BendyFinaleController.Update))] 43 | private static bool FixBendyEncounter(CH1BendyFinaleController __instance) 44 | { 45 | //if (__instance.m_CanScare && !__instance.m_InkMachineMeshRenderer.isVisible) 46 | // Logs.WriteInfo("Can't See the Ink Machine!!!"); 47 | 48 | if (__instance.m_ShowRunTutorial && PlayerInput.Run()) 49 | { 50 | GameManager.Instance.HideTutorial(); 51 | __instance.m_ShowRunTutorial = false; 52 | } 53 | //if (__instance.m_CanScare && m_InkMachineMeshRenderer.isVisible) 54 | if (__instance.m_CanScare) 55 | { 56 | __instance.m_BnedyEventTrigger.OnEnter -= __instance.HandleBendyEventTriggerOnEnter; 57 | __instance.m_BnedyEventTrigger.OnExit -= __instance.HandleBendyEventTriggerOnExit; 58 | __instance.m_BnedyEventTrigger.Dispose(); 59 | __instance.m_InkMachineMeshRenderer.enabled = false; 60 | __instance.m_CanScare = false; 61 | __instance.m_HasEffects = true; 62 | Sequence s = DOTween.Sequence(); 63 | float num = 0f; 64 | s.InsertCallback(num, __instance.ActualActivate); 65 | s.InsertCallback(num + 2f, delegate 66 | { 67 | __instance.m_Music = GameManager.Instance.AudioManager.Play(__instance.m_MusicClip, AudioObjectType.MUSIC, -1); 68 | }); 69 | Transform target = GameManager.Instance.GameCamera.InitializeFreeRoamCam(); 70 | GameManager.Instance.Player.GoToAndLookAt(__instance.m_HenryFallLocation); 71 | s.InsertCallback(num, delegate 72 | { 73 | GameManager.Instance.GameCamera.transform.DOShakePosition(3f, 0.6f, 15); 74 | }); 75 | s.Insert(num, target.DOLookAt(__instance.m_BendyLookAt.position, 0.2f).SetEase(Ease.Linear)); 76 | num += 0.4f; 77 | s.Insert(num, target.DOMoveX(__instance.m_HenryFallLocation.position.x, 0.5f).SetEase(Ease.Linear)); 78 | s.Insert(num, target.DOMoveZ(__instance.m_HenryFallLocation.position.z, 0.5f).SetEase(Ease.Linear)); 79 | num += 0.35f; 80 | s.Insert(num, target.DOMoveY(__instance.m_HenryFallLocation.position.y - 2f, 0.15f).SetEase(Ease.Linear)); 81 | s.InsertCallback(num + 0.15f, delegate 82 | { 83 | GameManager.Instance.AudioManager.Play(__instance.m_HenryBodyFallClip); 84 | }); 85 | s.Insert(num, target.DORotate(new Vector3(-70f, -15f, 20f), 0.4f).SetEase(Ease.Linear)); 86 | num += 0.75f; 87 | s.InsertCallback(num, delegate 88 | { 89 | __instance.m_BENDY.SetActive(value: false); 90 | }); 91 | s.Insert(num, target.DORotate(__instance.m_HenryFallLocation.eulerAngles, 1f).SetEase(Ease.InOutQuad)); 92 | s.Insert(num, target.DOMove(GameManager.Instance.Player.HeadContainer.position, 1f).SetEase(Ease.InOutQuad)); 93 | s.InsertCallback(num + 1f, delegate 94 | { 95 | GameManager.Instance.GameCamera.ExitFreeRoamCam(); 96 | GameManager.Instance.Player.SetLock(active: false); 97 | GameManager.Instance.ShowTutorial(new TutorialDataVO("Tutorial/TUTORIAL_RUN")); 98 | __instance.m_ShowRunTutorial = true; 99 | }); 100 | num += 1.5f; 101 | s.InsertCallback(num, delegate 102 | { 103 | GameManager.Instance.ShowObjective(ObjectiveDataVO.Create("OBJECTIVES/NEW_OBJECTIVE_HEADER", "OBJECTIVES/CH1_OBJ_06", string.Empty, 2f, isCurrentObjective: false, 1.75f)); 104 | }); 105 | } 106 | return false; 107 | } 108 | 109 | [HarmonyPrefix] 110 | [HarmonyPatch(typeof(CH1BendyFinaleController), nameof(CH1BendyFinaleController.ShakeCamera))] 111 | private static bool DontShakeCamera() 112 | { 113 | return false; 114 | } 115 | 116 | [HarmonyPrefix] 117 | [HarmonyPatch(typeof(CH1FinaleController), nameof(CH1FinaleController.HandleAxeOnEquipped))] 118 | private static bool DontShowTutorial(CH1FinaleController __instance) 119 | { 120 | //GameManager.Instance.ShowTutorial(new TutorialDataVO("Tutorial/TUTORIAL_ATTACK")); 121 | //m_ShowAttackTutorial = true; 122 | GameManager.Instance.ShowDialogue(DialogueDataVO.Create(__instance.m_HenryClip07, "DIACH1/DIA_CH1_HENRY_07")); 123 | for (int i = 0; i < __instance.m_Breakables.Count; i++) 124 | { 125 | __instance.m_Breakables[i].OnBroken += __instance.HandleOnBroken; 126 | } 127 | return false; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /BendyVR_5/src/Chapters/Patches/CH2Fixes.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using BendyVR_5.Stage; 4 | using BendyVR_5.UI; 5 | using DG.Tweening; 6 | using HarmonyLib; 7 | using TMG.Controls; 8 | using TMG.Core; 9 | using UnityEngine; 10 | using UnityEngine.VR; 11 | using UnityEngine.XR; 12 | 13 | 14 | namespace BendyVR_5.Chapters.Patches; 15 | 16 | [HarmonyPatch] 17 | public class CH2Fixes : BendyVRPatch 18 | { 19 | /*[HarmonyPrefix] 20 | [HarmonyPatch(typeof(CH2OpeningSequenceController), nameof(CH2OpeningSequenceController.DOOpeningSequence))] 21 | public static bool CH2OpeningFix(CH2OpeningSequenceController __instance, ref Sequence __result) 22 | { 23 | __result = DOTween.Sequence(); 24 | Logs.WriteWarning("Playing Hurt Border"); 25 | 26 | float num = 1f; 27 | float duration = 1f; 28 | __result.InsertCallback(num, delegate 29 | { 30 | GameManager.Instance.AudioManager.Play(__instance.m_TitleMusicClip, AudioObjectType.MUSIC); 31 | GameManager.Instance.ShowHurtBorder(isSilent: true); 32 | }); 33 | num += 5f; 34 | 35 | Logs.WriteWarning("Show Chapter Title"); 36 | 37 | __result.InsertCallback(num, delegate 38 | { 39 | GameManager.Instance.ShowChapterTitle("MENU/CH2_LABEL", "MENU/CH2_TITLE", showBlocker: false); 40 | }); 41 | num += 2f; 42 | 43 | Logs.WriteWarning("Show Hurt Borders"); 44 | 45 | for (int i = 0; i < 4; i++) 46 | { 47 | __result.InsertCallback(num, delegate 48 | { 49 | GameManager.Instance.ShowHurtBorder(isSilent: true); 50 | }); 51 | } 52 | __result.InsertCallback(num, __instance.PlayIntroDialogue_01); 53 | __result.InsertCallback(num, delegate 54 | { 55 | GameManager.Instance.HideScreenBlocker(duration); 56 | }); 57 | num += duration; 58 | duration = 0.5f; 59 | 60 | Logs.WriteWarning("Show Screen Blocker"); 61 | 62 | __result.InsertCallback(num, delegate 63 | { 64 | GameManager.Instance.ShowScreenBlocker(duration); 65 | }); 66 | num += duration + 0.75f; 67 | 68 | Logs.WriteWarning("Hide Screen Blocker"); 69 | 70 | __result.InsertCallback(num, delegate 71 | { 72 | GameManager.Instance.HideScreenBlocker(duration); 73 | }); 74 | num += duration + 0.25f; 75 | 76 | Logs.WriteWarning("Setting Focal Distance"); 77 | 78 | if (__instance.m_GameCam.DoF) 79 | { 80 | __instance.m_GameCam.UnityDOF.manualDOF = true; 81 | float distance = __instance.m_GameCam.UnityDOF.focalDistance; 82 | __result.Insert(num, DOTween.To(() => distance, delegate (float value) 83 | { 84 | distance = value; 85 | }, 5f, 2f).SetEase(Ease.Linear).OnUpdate(delegate 86 | { 87 | __instance.m_GameCam.UnityDOF.focalDistance = distance; 88 | })); 89 | } 90 | 91 | Logs.WriteWarning("Show Screen Blocker"); 92 | 93 | num += 1.5f; 94 | __result.InsertCallback(num, delegate 95 | { 96 | GameManager.Instance.ShowScreenBlocker(); 97 | }); 98 | num += 0.6f; 99 | 100 | Logs.WriteWarning("Unset DOF"); 101 | 102 | if (__instance.m_GameCam.DoF) 103 | { 104 | __result.InsertCallback(num, delegate 105 | { 106 | __instance.m_GameCam.UnityDOF.manualDOF = false; 107 | }); 108 | } 109 | 110 | Logs.WriteWarning("Hide Screen Blocker"); 111 | 112 | __result.InsertCallback(num, delegate 113 | { 114 | GameManager.Instance.HideScreenBlocker(); 115 | }); 116 | 117 | return false; 118 | }*/ 119 | 120 | [HarmonyPrefix] 121 | [HarmonyPatch(typeof(CH2OpeningSequenceController), nameof(CH2OpeningSequenceController.Activate))] 122 | public static bool VRActivateOpening(CH2OpeningSequenceController __instance) 123 | { 124 | if (GameManager.Instance.GameData.CurrentSaveFile.CH2Data.RitualObjective.IsComplete) 125 | { 126 | __instance.ForceComplete(); 127 | return false; 128 | } 129 | __instance.m_GameCam = GameManager.Instance.GameCamera; 130 | /*m_GameCamTransform = GameManager.Instance.GameCamera.InitializeFreeRoamCam(); 131 | m_GameCamTransform.position = m_StartPosition.position; 132 | m_GameCamTransform.eulerAngles = m_StartPosition.eulerAngles;*/ 133 | if (__instance.m_GameCam.DoF) 134 | { 135 | __instance.m_GameCam.UnityDOF.manualDOF = true; 136 | __instance.m_GameCam.UnityDOF.focalDistance = 0f; 137 | } 138 | __instance.DOOpeningSequence(); 139 | return false; 140 | } 141 | 142 | //Get rid of VR nausea simulator (CH2 Opening) 143 | [HarmonyPrefix] 144 | [HarmonyPatch(typeof(CH2OpeningSequenceController), nameof(CH2OpeningSequenceController.DOGetUpSequence))] 145 | private static bool DontGetUp(CH2OpeningSequenceController __instance, ref Sequence __result) 146 | { 147 | Sequence sequence = DOTween.Sequence(); 148 | float num = 1f; 149 | /*sequence.InsertCallback(num, delegate 150 | { 151 | __instance.m_GameCam.Camera.transform.SetParent(GameManager.Instance.Player.CameraParent); 152 | });*/ 153 | sequence.InsertCallback(num += 0.5f, __instance.PlayIntroDialogue_02); 154 | __result = sequence; 155 | return false; 156 | } 157 | 158 | [HarmonyPrefix] 159 | [HarmonyPatch(typeof(CH2OpeningSequenceController), nameof(CH2OpeningSequenceController.GetUpSequenceOnComplete))] 160 | public static bool DontGetUpOnComplete(CH2OpeningSequenceController __instance) 161 | { 162 | //GameManager.Instance.GameCamera.ExitFreeRoamCam(); 163 | __instance.PlayIntroDialogue_03(); 164 | GameManager.Instance.Player.SetLock(active: false); 165 | GameManager.Instance.UnlockPause(); 166 | GameManager.Instance.Player.SetInteraction(active: true); 167 | GameManager.Instance.Player.SetCameraSway(active: true); 168 | return false; 169 | } 170 | 171 | [HarmonyPrefix] 172 | [HarmonyPatch(typeof(CH2RitualRoomController), nameof(CH2RitualRoomController.ForceComplete))] 173 | private static bool VRCH2RitualRoomControllerComplete(CH2RitualRoomController __instance) 174 | { 175 | GameManager.Instance.UpdateObjective(ObjectiveDataVO.Create("OBJECTIVES/CURRENT_OBJECTIVE_HEADER", "OBJECTIVES/OBJECTIVE_FIND_A_NEW_EXIT", string.Empty)); 176 | GameManager.Instance.Player.WeaponGameObject = __instance.m_Axe.gameObject; 177 | GameManager.Instance.Player.EquipWeapon(); 178 | if ((bool)__instance.m_Axe && __instance.m_Axe.Interaction != null) 179 | { 180 | __instance.m_Axe.Interaction.SetActive(active: false); 181 | } 182 | __instance.m_Axe.KillInteraction(); 183 | __instance.m_Axe.Equip(); 184 | 185 | __instance.m_Plank.gameObject.SetActive(value: false); 186 | __instance.m_ScarePlank.gameObject.SetActive(value: false); 187 | __instance.m_Door.ForceOpen(145f); 188 | __instance.m_Door.Lock(); 189 | __instance.SendOnComplete(); 190 | 191 | return false; 192 | } 193 | 194 | 195 | 196 | [HarmonyPrefix] 197 | [HarmonyPatch(typeof(CH2ClosingSequenceController), nameof(CH2ClosingSequenceController.HandleFinalTriggerOnEnter))] 198 | private static bool VRHandleFinalTriggerOnEnter(CH2ClosingSequenceController __instance) 199 | { 200 | __instance.m_FinalTrigger.OnEnter -= __instance.HandleFinalTriggerOnEnter; 201 | GameManager.Instance.HideCrosshair(); 202 | GameManager.Instance.LockPause(); 203 | GameManager.Instance.Player.SetCameraSway(active: true); 204 | GameManager.Instance.Player.SetLock(active: true); 205 | //GameManager.Instance.Player.HeadContainer.DOLookAt(__instance.m_FinalLookAt.position, 2f).SetEase(Ease.InOutQuad); 206 | //VrCore.instance.GetVRPlayerController().mNewCameraParent.DOLookAt(__instance.m_FinalLookAt.position, 2f).SetEase(Ease.InOutQuad); 207 | 208 | //TODO Might remove this completely - since if they turn around physically it will be off. 209 | VrCore.instance.GetVRPlayerController().mPlayerController.transform.DOLookAt(__instance.m_FinalLookAt.position, 2f).SetEase(Ease.InOutQuad); 210 | GameManager.Instance.AudioManager.Play(__instance.m_CanKickClip); 211 | __instance.DOSequence().OnComplete(__instance.SequenceOnComplete); 212 | return false; 213 | } 214 | 215 | 216 | 217 | [HarmonyPrefix] 218 | [HarmonyPatch(typeof(CH2BendyChaseController), nameof(CH2BendyChaseController.HandleBendyOnEntered))] 219 | private static bool FixBendyEncounter(CH2BendyChaseController __instance) 220 | { 221 | __instance.m_BendyTrigger.OnEnter -= __instance.HandleBendyOnEntered; 222 | __instance.m_BendyTrigger.Dispose(); 223 | for (int i = 0; i < __instance.m_DisableGameObjects.Count; i++) 224 | { 225 | __instance.m_DisableGameObjects[i].SetActive(value: true); 226 | } 227 | for (int j = 0; j < __instance.m_ActiveGameObjects.Count; j++) 228 | { 229 | __instance.m_ActiveGameObjects[j].SetActive(value: false); 230 | } 231 | for (int k = 0; k < __instance.m_DisableSpawners.Length; k++) 232 | { 233 | __instance.m_DisableSpawners[k].SetActive(value: false); 234 | } 235 | for (int l = 0; l < __instance.m_EnableSpawners.Length; l++) 236 | { 237 | __instance.m_EnableSpawners[l].SetActive(value: true); 238 | } 239 | GameManager.Instance.AudioManager.Play(__instance.m_CeilingCollapseClip); 240 | GameManager.Instance.AudioManager.Play(__instance.m_CelingSettleClip); 241 | __instance.BendyReveal(); 242 | __instance.m_DoorController.Open(0f, Ease.Linear, -125f); 243 | __instance.m_BarricadeTrigger.SetActive(active: true); 244 | __instance.m_BarricadeTrigger.OnEnter += __instance.HandleBarricadeTriggerOnEnter; 245 | GameManager.Instance.CurrentChapter.DeathController.OnDeath += __instance.HandlePlayerOnDeath; 246 | 247 | return false; 248 | } 249 | } 250 | 251 | -------------------------------------------------------------------------------- /BendyVR_5/src/Chapters/Patches/CH3Fixes.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using BendyVR_5.Stage; 4 | using BendyVR_5.UI; 5 | using DG.Tweening; 6 | using HarmonyLib; 7 | using System; 8 | using System.Collections; 9 | using TMG.Controls; 10 | using TMG.Core; 11 | using UnityEngine; 12 | using UnityEngine.VR; 13 | using UnityEngine.XR; 14 | 15 | namespace BendyVR_5.Chapters.Patches; 16 | 17 | [HarmonyPatch] 18 | public class CH3Fixes : BendyVRPatch 19 | { 20 | [HarmonyPrefix] 21 | [HarmonyPatch(typeof(CH3OpeningSequenceController), nameof(CH3OpeningSequenceController.InternalActivate))] 22 | private static bool InternalActivate(CH3OpeningSequenceController __instance) 23 | { 24 | //__instance.m_GameCamTransform = GameManager.Instance.GameCamera.InitializeFreeRoamCam(); 25 | //__instance.m_GameCamTransform.position = __instance.m_BedPosition.position; 26 | //__instance.m_GameCamTransform.eulerAngles = __instance.m_BedPosition.eulerAngles; 27 | GameManager.Instance.ShowChapterTitle("MENU/CH3_LABEL", "MENU/CH3_TITLE"); 28 | GameManager.Instance.HideScreenBlocker(1f); 29 | //__instance.DOSequence(); 30 | //GameManager.Instance.GameCamera.ExitFreeRoamCam(); 31 | GameManager.Instance.Player.SetLock(active: false); 32 | GameManager.Instance.UnlockPause(); 33 | //GameManager.Instance.Player.SetCameraSway(active: true); 34 | //GameManager.Instance.ShowCrosshair(); 35 | GameManager.Instance.ShowObjective(ObjectiveDataVO.Create("OBJECTIVES/NEW_OBJECTIVE_HEADER", "OBJECTIVES/CH3_OBJECTIVE_01", string.Empty, 4f)); 36 | __instance.SendOnComplete(); 37 | return false; 38 | } 39 | 40 | 41 | [HarmonyPrefix] 42 | [HarmonyPatch(typeof(CH3WeaponStationController), nameof(CH3WeaponStationController.HandleDropboxOnInteracted))] 43 | private static bool FixWeaponSwitch(CH3WeaponStationController __instance) 44 | { 45 | __instance.m_Dropbox.OnInteracted -= __instance.HandleDropboxOnInteracted; 46 | __instance.m_Dropbox.SetActive(active: false); 47 | GameManager.Instance.AudioManager.PlayAtPosition(__instance.m_DropboxClip, __instance.m_Dropbox.transform.position); 48 | PlayerController player = GameManager.Instance.Player; 49 | if ((bool)player.InactiveWeapon) 50 | { 51 | UnityEngine.Object.Destroy(player.WeaponGameObject); 52 | player.WeaponGameObject = player.InactiveWeapon; 53 | player.WeaponGameObject.SetActive(value: true); 54 | player.WeaponGameObject.transform.localPosition = Vector3.zero; 55 | player.WeaponGameObject.transform.localEulerAngles = Vector3.zero; 56 | player.InactiveWeapon = null; 57 | VrCore.instance.GetVRPlayerController().SetupMeleeWeapon(player.WeaponGameObject.name); 58 | } 59 | return false; 60 | } 61 | 62 | [HarmonyPrefix] 63 | [HarmonyPatch(typeof(CH3ProjectionistTaskController), nameof(CH3ProjectionistTaskController.HandleGunOnInteracted))] 64 | private static bool FixElevator(CH3ProjectionistTaskController __instance, object sender, EventArgs e) 65 | { 66 | (sender as Interactable).OnInteracted -= __instance.HandleGunOnInteracted; 67 | if (!__instance.m_CanHaveTommyGun) 68 | { 69 | GameManager.Instance.ShowDialogue(DialogueDataVO.Create(__instance.m_AliceTommyGunFakeClip, "DIACH3/DIA_CH3_ALICE_22")); 70 | } 71 | else 72 | { 73 | GameManager.Instance.AchievementManager.SetAchievement(AchievementName.BLAZING_METAL); 74 | } 75 | ObjectiveDataVO objectiveDataVO = ObjectiveDataVO.Create("OBJECTIVES/NEW_OBJECTIVE_HEADER", "OBJECTIVES/CH3_OBJECTIVE_TASK_PROJECTIONIST", "OBJECTIVES/CH3_OBJECTIVE_TASK_PROJECTIONIST_TIP", 4f); 76 | objectiveDataVO.AddItemCounter(__instance.m_ObjectiveSprite, 0); 77 | GameManager.Instance.ShowObjective(objectiveDataVO); 78 | __instance.m_WeaponStationController.Unblock(); 79 | GameManager.Instance.GameData.CurrentSaveFile.CH3Data.HeartTask.Status.IsStarted = true; 80 | GameManager.Instance.GameData.CurrentSaveFile.CH3Data.LiftFloor = __instance.m_LiftController.CurrentFloor.ID; 81 | //This was missing! 82 | __instance.m_LiftController.EnableLift(); 83 | GameManager.Instance.GameDataManager.Save(); 84 | __instance.EnableTask(); 85 | return false; 86 | } 87 | 88 | /*[HarmonyPrefix] 89 | [HarmonyPatch(typeof(CH3ProjectionistTaskController), nameof(CH3ProjectionistTaskController.CheckTommyGun))] 90 | private static bool TommyGunCheat(ref bool __result) 91 | { 92 | __result = true; //Force Tommy Gun On 93 | return false; 94 | }*/ 95 | 96 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Chapters/Patches/CH4Fixes.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using BendyVR_5.Stage; 4 | using BendyVR_5.UI; 5 | using DG.Tweening; 6 | using HarmonyLib; 7 | using S13Audio; 8 | using System; 9 | using System.Collections; 10 | using TMG.Controls; 11 | using TMG.Core; 12 | using UnityEngine; 13 | using UnityEngine.VR; 14 | using UnityEngine.XR; 15 | 16 | namespace BendyVR_5.Chapters.Patches; 17 | 18 | [HarmonyPatch] 19 | public class CH4Fixes : BendyVRPatch 20 | { 21 | [HarmonyPrefix] 22 | [HarmonyPatch(typeof(BruteBorisAi), nameof(BruteBorisAi.ApplyShake))] 23 | private static bool DontShakeCamera() 24 | { 25 | return false; 26 | } 27 | 28 | [HarmonyPrefix] 29 | [HarmonyPatch(typeof(CH4BallroomController), nameof(CH4BallroomController.HandleBorisOnDeath))] 30 | private static bool VRHandleBorisOnDeath(CH4BallroomController __instance) 31 | { 32 | __instance.m_Boris.OnDeath -= __instance.HandleBorisOnDeath; 33 | if (GameManager.Instance.GameData.CurrentSaveFile.CH4Data.HasPlunger) 34 | { 35 | GameManager.Instance.AchievementManager.SetAchievement(AchievementName.UNLIKELY_VICTORY); 36 | } 37 | if ((bool)__instance.m_MusicLoop) 38 | { 39 | __instance.m_MusicLoop.Stop(); 40 | __instance.m_MusicLoop = null; 41 | } 42 | if ((bool)GameManager.Instance.Player.WeaponGameObject) 43 | { 44 | GameManager.Instance.Player.WeaponGameObject.SetActive(value: false); 45 | } 46 | __instance.ClearThickInk(); 47 | GameManager.Instance.AudioManager.Play(__instance.m_MusicDeathOfAFriendFinisher, AudioObjectType.MUSIC); 48 | for (int i = 0; i < __instance.m_AliceFinaleClips.Length; i++) 49 | { 50 | GameManager.Instance.ShowDialogue(DialogueDataVO.Create(__instance.m_AliceFinaleClips[i], SubtitleConstants.DIA_CH4_ALICE_FINALE[i], isTrimmed: true)); 51 | } 52 | GameManager.Instance.LockPause(); 53 | GameManager.Instance.HideCrosshair(); 54 | GameManager.Instance.Player.SetCollision(active: false); 55 | GameManager.Instance.Player.SetCameraSway(active: true); 56 | Transform target = GameManager.Instance.GameCamera.InitializeFreeRoamCam(); 57 | Vector3 position = __instance.m_Boris.transform.position; 58 | position -= __instance.m_Boris.transform.forward * 5f; 59 | Sequence sequence = DOTween.Sequence(); 60 | float num = 0.5f; 61 | //Don't move 62 | //sequence.Insert(num, target.DOMove(m_PlayerEndLocation.position, 2f).SetEase(Ease.InOutQuad)); 63 | //sequence.Insert(num, target.DORotate(m_PlayerEndLocation.eulerAngles, 2f).SetEase(Ease.InOutQuad)); 64 | num += 2f; 65 | //sequence.Insert(num, target.DOLookAt(position, 2f).SetEase(Ease.InOutQuad)); 66 | sequence.OnComplete(__instance.SendOnComplete); 67 | return false; 68 | } 69 | 70 | [HarmonyPrefix] 71 | [HarmonyPatch(typeof(CH4ClosingSequenceController), nameof(CH4ClosingSequenceController.Activate))] 72 | private static bool VRActivate(CH4ClosingSequenceController __instance) 73 | { 74 | GameManager.Instance.AudioManager.Play(__instance.m_BorisMusicClip, AudioObjectType.MUSIC).OnComplete += __instance.HandleBorisMusicOnComplete; 75 | __instance.m_FreeRoamCamera = GameManager.Instance.GameCamera.InitializeFreeRoamCam(); 76 | GameManager.Instance.LockPause(); 77 | GameManager.Instance.HideCrosshair(); 78 | GameManager.Instance.Player.SetCameraSway(active: true); 79 | //__instance.m_FreeRoamCamera.DOMove(__instance.m_BorisLookLocation.position, 12f).SetEase(Ease.InOutQuad); 80 | //__instance.m_FreeRoamCamera.DORotate(__instance.m_BorisLookLocation.eulerAngles, 12f).SetEase(Ease.InOutQuad); 81 | Sequence s = DOTween.Sequence(); 82 | float num = 2f; 83 | float num2 = 11f; 84 | s.InsertCallback(num, delegate 85 | { 86 | S13AudioManager.Instance.InvokeEvent("evt_boris_death_melt"); 87 | }); 88 | s.Insert(num, __instance.m_BorisBody.materials[0].DOFloat(1f, "_MeltPercentage", num2).SetEase(Ease.Linear)); 89 | s.Insert(num, __instance.m_BorisBody.materials[1].DOFloat(1f, "_MeltPercentage", num2).SetEase(Ease.Linear)); 90 | num += num2; 91 | s.Insert(num, __instance.m_BorisBody.materials[0].DOFloat(1f, "_Dissolve", 4f).SetEase(Ease.Linear)); 92 | s.Insert(num, __instance.m_BorisBody.materials[1].DOFloat(1f, "_Dissolve", 4f).SetEase(Ease.Linear)); 93 | return false; 94 | } 95 | 96 | [HarmonyPrefix] 97 | [HarmonyPatch(typeof(CH4ClosingSequenceController), nameof(CH4ClosingSequenceController.ActualActivate))] 98 | private static bool VRActualActivate(CH4ClosingSequenceController __instance) 99 | { 100 | __instance.m_Alice.SetActive(value: true); 101 | __instance.m_Allison.SetActive(value: true); 102 | //__instance.m_FreeRoamCamera.DOMove(__instance.m_PlayerCamLocation.position, 1f).SetEase(Ease.Linear); 103 | //__instance.m_FreeRoamCamera.DORotate(__instance.m_PlayerCamLocation.eulerAngles, 1f).SetEase(Ease.Linear); 104 | //GameManager.Instance.Player.SetFOVValue(45f, 2.5f); 105 | return false; 106 | } 107 | 108 | [HarmonyPrefix] 109 | [HarmonyPatch(typeof(CH4ClosingSequenceController), nameof(CH4ClosingSequenceController.AliceFall))] 110 | public static bool AliceFall(CH4ClosingSequenceController __instance) 111 | { 112 | __instance.m_Tom.transform.position = __instance.m_BorisLocation.position; 113 | __instance.m_Tom.transform.eulerAngles = __instance.m_BorisLocation.eulerAngles; 114 | __instance.m_Tom.SetActive(value: true); 115 | //m_FreeRoamCamera.DOLookAt(m_FinalLookLocation.position, 4f).SetDelay(1f).SetEase(Ease.InOutQuad); 116 | return false; 117 | } 118 | 119 | [HarmonyPrefix] 120 | [HarmonyPatch(typeof(CH4ClosingSequenceController), nameof(CH4ClosingSequenceController.LookAtAlice))] 121 | public static bool LookAtAlice(CH4ClosingSequenceController __instance) 122 | { 123 | //__instance.m_FreeRoamCamera.DOLookAt(__instance.m_LookAtLocation.position, 1f).SetEase(Ease.InOutQuad); 124 | __instance.m_AudioSwitch.Play("fall"); 125 | return false; 126 | } 127 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Debugging/GeneralDebugger.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using InControl; 3 | using UnityEngine; 4 | 5 | namespace BendyVR_5.Debugging; 6 | 7 | public class GeneralDebugger : MonoBehaviour 8 | { 9 | /* 10 | private static void UpdateInputsDebug() 11 | { 12 | var inputManager = InputManager.Instance; 13 | if (!Input.GetKeyDown(KeyCode.Alpha9)) return; 14 | InputManager. 15 | Logs.WriteInfo("## Starting key bind logs##"); 16 | foreach (var bind in inputManager.virtualKeyKeyBindMap.Values) 17 | { 18 | Logs.WriteInfo("bind"); 19 | foreach (var command in bind.commands) Logs.WriteInfo($"command: {command.command}"); 20 | } 21 | 22 | foreach (var context in inputManager.contextStack) 23 | { 24 | Logs.WriteInfo($"## Context {context.name}:"); 25 | foreach (var mapping in context.commandMap) 26 | { 27 | Logs.WriteInfo($"# mapping: {mapping.virtualKey}"); 28 | foreach (var command in mapping.commands) Logs.WriteInfo($"command: {command.command}"); 29 | } 30 | } 31 | 32 | Logs.WriteInfo("## Virtual keys: ##"); 33 | foreach (var item in inputManager.customLayout.mapping) Logs.WriteInfo($"virtual key: {item.virtualKey}"); 34 | 35 | Logs.WriteInfo("## Ended key bind logs ##"); 36 | }*/ 37 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/CopyLocalTransformValues.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.src; 2 | using UnityEngine; 3 | 4 | namespace BendyVR_5.Helpers; 5 | 6 | public class CopyLocalTransformValues : BendyVRBehavior 7 | { 8 | private Transform target; 9 | 10 | public static void Create(GameObject gameObject, Transform target) 11 | { 12 | var instance = gameObject.GetComponent(); 13 | if (!instance) instance = gameObject.AddComponent(); 14 | 15 | instance.target = target; 16 | } 17 | 18 | protected override void VeryLateUpdate() 19 | { 20 | if (!target) 21 | { 22 | Destroy(this); 23 | return; 24 | } 25 | Logs.WriteInfo("CLTV Setting " + transform.name + " to " + target.name); 26 | transform.localRotation = target.localRotation; 27 | transform.localPosition = target.localPosition; 28 | transform.localScale = target.localScale; 29 | } 30 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/FakeParenting.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.src; 2 | using System; 3 | using UnityEngine; 4 | 5 | namespace BendyVR_5.Helpers; 6 | 7 | // This component is useful when we need to simulate object parenting, 8 | // without actually changing the hierarchy. 9 | public class FakeParenting : BendyVRBehavior 10 | { 11 | [Flags] 12 | public enum UpdateType 13 | { 14 | None = 0, 15 | LateUpdate = 1, 16 | VeryLateUpdate = 2 17 | } 18 | 19 | public enum TransformType 20 | { 21 | All = 0, 22 | Delta = 1, 23 | DeltaInverse = 2, 24 | DeltaTransformOnly = 3, 25 | DeltaInverseTransformOnly = 4, 26 | TransformOnly = 5, 27 | RotationOnly = 6 28 | } 29 | 30 | private TransformType transformType; 31 | private Transform target; 32 | private UpdateType updateTypes; 33 | private Vector3 lastPosition = new Vector3(0f, 0f, 0f); 34 | private Quaternion lastRotation; 35 | 36 | public static FakeParenting Create(Transform transform, Transform target = null, 37 | UpdateType updateType = UpdateType.VeryLateUpdate, 38 | TransformType transformType = TransformType.All) 39 | { 40 | var instance = transform.GetComponent(); 41 | if (!instance) instance = transform.gameObject.AddComponent(); 42 | instance.target = target; 43 | instance.updateTypes = updateType; 44 | instance.transformType = transformType; 45 | 46 | Logs.WriteWarning(transform.gameObject.name + " is now following " + target.gameObject.name + " (" + transformType.ToString() + ")"); 47 | 48 | return instance; 49 | } 50 | 51 | private void LateUpdate() 52 | { 53 | if (!IsUpdateType(UpdateType.LateUpdate)) return; 54 | UpdateTransform(); 55 | } 56 | 57 | protected override void VeryLateUpdate() 58 | { 59 | if (!IsUpdateType(UpdateType.VeryLateUpdate)) return; 60 | UpdateTransform(); 61 | } 62 | 63 | private bool IsUpdateType(UpdateType type) 64 | { 65 | return (updateTypes & type) != UpdateType.None; 66 | } 67 | 68 | public void SetTarget(Transform newTarget) 69 | { 70 | target = newTarget; 71 | } 72 | 73 | private void UpdateTransform() 74 | { 75 | if (!target) return; 76 | 77 | if (transformType.Equals(TransformType.All) || 78 | transformType.Equals(TransformType.RotationOnly) || 79 | transformType.Equals(TransformType.TransformOnly)) 80 | { 81 | if(!transformType.Equals(TransformType.RotationOnly)) 82 | transform.position = target.position; 83 | if (!transformType.Equals(TransformType.TransformOnly)) 84 | transform.rotation = target.rotation; 85 | } 86 | else if (transformType.Equals(TransformType.Delta) || 87 | transformType.Equals(TransformType.DeltaInverse) || 88 | transformType.Equals(TransformType.DeltaTransformOnly) || 89 | transformType.Equals(TransformType.DeltaInverseTransformOnly)) 90 | { 91 | //Velocity Delta 92 | if (!lastPosition.Equals(new Vector3(0f, 0f, 0f))) 93 | { 94 | Vector3 posChange = target.localPosition - lastPosition; 95 | lastPosition = target.localPosition; 96 | 97 | //Angular Velocity 98 | Quaternion deltaRotation = target.localRotation * Quaternion.Inverse(lastRotation); 99 | lastRotation = target.localRotation; 100 | 101 | if (transformType.Equals(TransformType.DeltaTransformOnly) || transformType.Equals(TransformType.Delta)) 102 | { 103 | transform.position += posChange; 104 | if (transformType.Equals(TransformType.Delta)) 105 | transform.rotation *= deltaRotation; 106 | } 107 | else 108 | { 109 | transform.position -= posChange; 110 | if (transformType.Equals(TransformType.DeltaInverse)) 111 | transform.rotation *= Quaternion.Inverse(deltaRotation); 112 | } 113 | } 114 | else 115 | { 116 | lastPosition = target.localPosition; 117 | lastRotation = target.localRotation; 118 | } 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/LayerHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace BendyVR_5.Helpers; 5 | 6 | public enum GameLayer 7 | { 8 | // Layers included in base game: 9 | Default = 0, 10 | TransparentFX = 1, 11 | IgnoreRaycast = 2, // Note: layer name is actually "Ignore Raycast". 12 | Water = 4, 13 | UI = 5, 14 | PlayerOnly = 8, 15 | Terrain = 9, 16 | DynamicObjects = 10, 17 | RaycastOnly = 11, 18 | StopsPlayer = 12, 19 | MenuBackground = 13, 20 | RopeClimbCollision = 14, 21 | PhysicsHackCollision = 15, 22 | PutBack = 16, 23 | FullscreenScaledQuad = 17, 24 | Collision64 = 18, 25 | TempCast = 19, 26 | 27 | // Custom VR layers: 28 | PlayerBody = 30, 29 | VrHands = 31 30 | } 31 | 32 | public static class LayerHelper 33 | { 34 | public static int GetMask(GameLayer layer, int baseMask = 0) 35 | { 36 | return baseMask | (1 << (int) layer); 37 | } 38 | 39 | public static int GetMask(params GameLayer[] layers) 40 | { 41 | if (layers == null) throw new ArgumentNullException(nameof(layers)); 42 | var result = 0; 43 | foreach (var layer in layers) result = GetMask(layer, result); 44 | 45 | return result; 46 | } 47 | 48 | public static void SetLayer(Component component, GameLayer layer) 49 | { 50 | SetLayer(component.gameObject, layer); 51 | } 52 | 53 | public static void SetLayer(GameObject gameObject, GameLayer layer) 54 | { 55 | gameObject.layer = (int) layer; 56 | } 57 | 58 | public static void SetLayerRecursive(GameObject gameObject, GameLayer layer) 59 | { 60 | SetLayer(gameObject, layer); 61 | foreach (Transform child in gameObject.transform) SetLayerRecursive(child.gameObject, layer); 62 | } 63 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/Logs.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.src; 2 | using UnityEngine; 3 | 4 | namespace BendyVR_5.Helpers; 5 | 6 | public static class Logs 7 | { 8 | // ReSharper disable Unity.PerformanceAnalysis 9 | public static void WriteInfo(object data) 10 | { 11 | BendyVRPlugin.logBendyVR.LogInfo(data); 12 | } 13 | 14 | // ReSharper disable Unity.PerformanceAnalysis 15 | public static void WriteWarning(object data) 16 | { 17 | BendyVRPlugin.logBendyVR.LogWarning(data); 18 | } 19 | 20 | // ReSharper disable Unity.PerformanceAnalysis 21 | public static void WriteError(object data) 22 | { 23 | BendyVRPlugin.logBendyVR.LogError(data); 24 | } 25 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/MaterialHelper.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Rendering; 3 | using UnityEngine.UI; 4 | 5 | namespace BendyVR_5.Helpers; 6 | 7 | public static class MaterialHelper 8 | { 9 | private static void MakeMaterialDrawOnTop(Material material) 10 | { 11 | material.shader = Canvas.GetDefaultCanvasMaterial().shader; 12 | material.SetInt(ShaderProperty.UnityGuizTestMode, (int) CompareFunction.Always); 13 | } 14 | 15 | private static void MakeGraphicDrawOnTop(Graphic graphic) 16 | { 17 | if (graphic.material == Canvas.GetDefaultCanvasMaterial()) 18 | graphic.material = new Material(graphic.material); 19 | MakeMaterialDrawOnTop(graphic.material); 20 | } 21 | 22 | public static void MakeGraphicChildrenDrawOnTop(GameObject parent) 23 | { 24 | var graphics = parent.GetComponentsInChildren(true); 25 | foreach (var graphic in graphics) MakeGraphicDrawOnTop(graphic); 26 | } 27 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/MathHelper.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace BendyVR_5.Helpers; 4 | 5 | public static class MathHelper 6 | { 7 | private const float cos45 = 0.70710678f; 8 | 9 | public static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis, float unsignedAngle) 10 | { 11 | var crossX = from.y * to.z - from.z * to.y; 12 | var crossY = from.z * to.x - from.x * to.z; 13 | var crossZ = from.x * to.y - from.y * to.x; 14 | var sign = Mathf.Sign(axis.x * crossX + axis.y * crossY + axis.z * crossZ); 15 | return unsignedAngle * sign; 16 | } 17 | 18 | public static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis) 19 | { 20 | var unsignedAngle = Vector3.Angle(from, to); 21 | return SignedAngle(from, to, axis, unsignedAngle); 22 | } 23 | 24 | public static Vector3 PositionAroundCircle(int index, int totalCount, float circleRadius) 25 | { 26 | var angle = index * Mathf.PI * 2f / totalCount; 27 | return new Vector3(Mathf.Cos(angle) * circleRadius, Mathf.Sin(angle) * circleRadius, 0); 28 | } 29 | 30 | public static float GetSquareDistance(Vector3 pointA, Vector3 pointB) 31 | { 32 | return (pointA - pointB).sqrMagnitude; 33 | } 34 | 35 | public static float GetSquareDistance(Transform transformA, Transform transformB) 36 | { 37 | return GetSquareDistance(transformA.position, transformB.position); 38 | } 39 | 40 | public static Vector2 ConvertCircleVectorToSquare(Vector2 input) 41 | { 42 | if (input.sqrMagnitude == 0) return Vector2.zero; 43 | 44 | var normal = input.normalized; 45 | float vectorX; 46 | float vectorY; 47 | 48 | if (normal.x != 0 && normal.y >= -cos45 && normal.y <= cos45) 49 | vectorX = normal.x >= 0 ? input.x / normal.x : -input.x / normal.x; 50 | else 51 | vectorX = input.x / Mathf.Abs(normal.y); 52 | 53 | if (normal.y != 0 && normal.x >= -cos45 && normal.x <= cos45) 54 | vectorY = normal.y >= 0 ? input.y / normal.y : -input.y / normal.y; 55 | else 56 | vectorY = input.y / Mathf.Abs(normal.x); 57 | 58 | return new Vector2(vectorX, vectorY); 59 | } 60 | 61 | public static Vector3 GetProjectedForward(Transform transform) 62 | { 63 | var forward = transform.forward; 64 | forward.y = 0; 65 | return forward; 66 | } 67 | 68 | public static Quaternion SmoothDamp(Quaternion rot, Quaternion target, ref Quaternion deriv, float time) 69 | { 70 | // account for double-cover 71 | var dot = Quaternion.Dot(rot, target); 72 | var multi = dot > 0f ? 1f : -1f; 73 | target.x *= multi; 74 | target.y *= multi; 75 | target.z *= multi; 76 | target.w *= multi; 77 | // smooth damp (nlerp approx) 78 | var result = new Vector4( 79 | SmoothDamp(rot.x, target.x, ref deriv.x, time), 80 | SmoothDamp(rot.y, target.y, ref deriv.y, time), 81 | SmoothDamp(rot.z, target.z, ref deriv.z, time), 82 | SmoothDamp(rot.w, target.w, ref deriv.w, time) 83 | ).normalized; 84 | // compute deriv 85 | var dtInv = 1f / Time.unscaledDeltaTime; 86 | deriv.x = (result.x - rot.x) * dtInv; 87 | deriv.y = (result.y - rot.y) * dtInv; 88 | deriv.z = (result.z - rot.z) * dtInv; 89 | deriv.w = (result.w - rot.w) * dtInv; 90 | return new Quaternion(result.x, result.y, result.z, result.w); 91 | } 92 | 93 | public static float SmoothDamp( 94 | float current, 95 | float target, 96 | ref float currentVelocity, 97 | float smoothTime) 98 | { 99 | return Mathf.SmoothDamp( 100 | current, 101 | target, 102 | ref currentVelocity, 103 | smoothTime, 104 | Mathf.Infinity, 105 | Time.unscaledDeltaTime); 106 | } 107 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/ShaderProperty.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace BendyVR_5.Helpers; 4 | 5 | public static class ShaderProperty 6 | { 7 | public static readonly int MainTexture = Shader.PropertyToID("_MainTex"); 8 | public static readonly int Color = Shader.PropertyToID("_Color"); 9 | public static readonly int UnityGuizTestMode = Shader.PropertyToID("unity_GUIZTestMode"); 10 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Helpers/TagHelper.cs: -------------------------------------------------------------------------------- 1 | namespace BendyVR_5.Helpers; 2 | 3 | public static class GameTag 4 | { 5 | public const string Untagged = "Untagged"; 6 | public const string MainCamera = "MainCamera"; 7 | public const string Main = "MAIN"; 8 | } -------------------------------------------------------------------------------- /BendyVR_5/src/LaserPointer/VrLaser.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.Settings; 3 | using BendyVR_5.Stage; 4 | using BendyVR_5.VrInput.ActionInputs; 5 | using UnityEngine; 6 | 7 | 8 | namespace BendyVR_5.LaserPointer; 9 | 10 | public class VrLaser : MonoBehaviour 11 | { 12 | public float laserLength = 1.5f; 13 | private readonly IActionInput actionInput = ActionInputDefinitions.Interact; 14 | 15 | private LineRenderer lineRenderer; 16 | 17 | public static VrLaser Create(Transform dominantHand) 18 | { 19 | var instance = new GameObject("VrHandLaser").AddComponent(); 20 | var instanceTransform = instance.transform; 21 | instanceTransform.SetParent(dominantHand, false); 22 | instanceTransform.localEulerAngles = new Vector3(39.132f, 356.9302f, 0.3666f); 23 | return instance; 24 | } 25 | 26 | private void Start() 27 | { 28 | //Trying to match length to shimmer 29 | lineRenderer = gameObject.AddComponent(); 30 | lineRenderer.useWorldSpace = false; 31 | lineRenderer.SetPositions(new[] {Vector3.zero, Vector3.forward * laserLength}); 32 | lineRenderer.startWidth = 0.005f; 33 | lineRenderer.endWidth = 0.001f; 34 | lineRenderer.endColor = new Color(1, 1, 1, 0.8f); 35 | lineRenderer.startColor = Color.clear; 36 | lineRenderer.material.shader = Shader.Find("Particles/Alpha Blended Premultiply"); 37 | //lineRenderer.material.shader = Shader.Find("Standard"); 38 | lineRenderer.material.SetColor(ShaderProperty.Color, Color.white); 39 | lineRenderer.sortingOrder = 10000; 40 | lineRenderer.enabled = false; 41 | } 42 | 43 | private void Update() 44 | { 45 | UpdateLaserVisibility(); 46 | } 47 | 48 | private void UpdateLaserVisibility() 49 | { 50 | if (VrSettings.ShowLaserPointer.Value && !VrCore.instance.GetVRPlayerController().mPlayerController.isSeeingToolActive) 51 | { 52 | lineRenderer.enabled = ActionInputDefinitions.Interact.AxisValue != 0; 53 | } 54 | } 55 | 56 | 57 | } -------------------------------------------------------------------------------- /BendyVR_5/src/Player/Patches/PlayerControllerPatches.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using DG.Tweening; 4 | using HarmonyLib; 5 | using System; 6 | using System.Collections.Generic; 7 | using TMG.Controls; 8 | using UnityEngine; 9 | using UnityEngine.UI; 10 | 11 | namespace BendyVR_5.Player.Patches; 12 | 13 | [HarmonyPatch] 14 | public class PlayerControllerPatches : BendyVRPatch 15 | { 16 | [HarmonyPrefix] 17 | [HarmonyPatch(typeof(PlayerController), nameof(PlayerController.FixedUpdate))] 18 | [HarmonyPatch(typeof(PlayerController), nameof(PlayerController.Update))] 19 | private static bool RemoveCorePlayerUpdates(PlayerController __instance) 20 | { 21 | return false; 22 | } 23 | 24 | [HarmonyPrefix] 25 | [HarmonyPatch(typeof(EventTrigger), nameof(EventTrigger.OnTriggerEnter))] 26 | private static void WhatAmICollidingWith(EventTrigger __instance, Collider col) 27 | { 28 | Logs.WriteWarning(__instance.transform.name + " Collided with " + col.transform.name); 29 | } 30 | 31 | [HarmonyPrefix] 32 | [HarmonyPatch(typeof(InteractableInputController), nameof(InteractableInputController.UpdateInteraction), new Type[] { typeof(Vector3), typeof(Vector3), typeof(float) }, new ArgumentType[] { ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal })] 33 | public static bool VRUpdateInteraction(InteractableInputController __instance, Vector3 origin, Vector3 direction, float distance) 34 | { 35 | if (!__instance.m_Active) 36 | { 37 | return false; 38 | } 39 | //if (Physics.SphereCast(origin, __instance.m_SphereCastThickness, direction, out var hitInfo, distance, ~(int)__instance.m_IgnoreLayers)) 40 | if (Physics.SphereCast(origin, 0.3f, direction, out var hitInfo, distance, ~(int)__instance.m_IgnoreLayers)) 41 | { 42 | Interactable component = hitInfo.transform.GetComponent(); 43 | if ((bool)component) 44 | { 45 | __instance.DrawDebugLine(origin, hitInfo.point, Color.yellow); 46 | if (__instance.Interactable != component) 47 | { 48 | __instance.ExitInteraction(); 49 | } 50 | __instance.Interactable = component; 51 | if (PlayerInput.InteractOnPressed()) 52 | { 53 | __instance.Interact(); 54 | } 55 | else 56 | { 57 | __instance.EnterInteraction(); 58 | } 59 | } 60 | else 61 | { 62 | __instance.ExitInteraction(); 63 | } 64 | } 65 | else 66 | { 67 | __instance.ExitInteraction(); 68 | } 69 | return false; 70 | } 71 | 72 | [HarmonyPrefix] 73 | [HarmonyPatch(typeof(HurtBordersController), nameof(HurtBordersController.ShowBorder))] 74 | public static bool VRShowBorder(HurtBordersController __instance, bool isSilent = false) 75 | { 76 | if (__instance.m_HitCount >= __instance.m_HitMax) 77 | { 78 | /*if (!__instance.m_IsHitMax) 79 | { 80 | GameManager.Instance.isDead = true; 81 | __instance.m_HitCount--; 82 | __instance.m_IsHitMax = true; 83 | __instance.m_BlackImage.DOKill(); 84 | __instance.m_BlackImage.DOFade(1f, 0.2f).SetEase(Ease.Linear); 85 | GameManager.Instance.ShowScreenBlocker(0f); 86 | GameManager.Instance.HideCrosshair(); 87 | __instance.PlayAudio(ref __instance.m_DeathClips); 88 | //How do I do this? 89 | //__instance.OnMaxHit.Send(__instance); 90 | __instance.OnMaxHit += __instance; 91 | }*/ 92 | return true; //If we are dying send through the original code 93 | } 94 | if (!isSilent) 95 | { 96 | __instance.PlayAudio(ref __instance.m_HurtClips); 97 | } 98 | __instance.m_IsHit = true; 99 | __instance.m_Timer = 0f; 100 | //Don't do any camera stuff 101 | /*Transform camera = GameManager.Instance.GameCamera.transform; 102 | camera.localPosition = Vector3.zero; 103 | camera.DOShakePosition(0.75f, 0.35f, 15).OnComplete(delegate 104 | { 105 | camera.localPosition = Vector3.zero; 106 | });*/ 107 | for (int i = 0; i < __instance.m_HitMax && i <= __instance.m_HitCount; i++) 108 | { 109 | Image image = __instance.m_Borders[i]; 110 | image.DOKill(); 111 | image.rectTransform.DOKill(); 112 | image.enabled = true; 113 | image.color = Color.white; 114 | image.rectTransform.localScale = Vector3.one; 115 | image.rectTransform.DOScale(1.005f, 0.25f + (float)i * 0.005f).SetEase(Ease.InOutQuad).SetLoops(-1, LoopType.Yoyo); 116 | } 117 | __instance.m_HitCount++; 118 | return false; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /BendyVR_5/src/Settings/VrSettings.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Player; 2 | using BendyVR_5.Stage; 3 | using BepInEx.Configuration; 4 | using System; 5 | using System.Linq; 6 | using UnityEngine; 7 | 8 | namespace BendyVR_5.Settings; 9 | 10 | public static class VrSettings 11 | { 12 | public enum SmoothRotationSpeedOption 13 | { 14 | VerySlow = 1, 15 | Slow = 2, 16 | Default = 3, 17 | Fast = 4, 18 | VeryFast = 5 19 | } 20 | 21 | public enum SnapTurnAngleOption 22 | { 23 | Angle23 = 23, 24 | Angle30 = 30, 25 | Angle45 = 45, 26 | Angle60 = 60, 27 | Angle90 = 90 28 | } 29 | 30 | public static T Next(this T src) where T : struct 31 | { 32 | if (!typeof(T).IsEnum) throw new ArgumentException(String.Format("Argument {0} is not an Enum", typeof(T).FullName)); 33 | 34 | T[] Arr = (T[])Enum.GetValues(src.GetType()); 35 | int j = Array.IndexOf(Arr, src) + 1; 36 | return (Arr.Length == j) ? Arr[0] : Arr[j]; 37 | } 38 | 39 | public static T Previous(this T src) where T : struct 40 | { 41 | if (!typeof(T).IsEnum) throw new ArgumentException(String.Format("Argument {0} is not an Enum", typeof(T).FullName)); 42 | 43 | T[] Arr = (T[])Enum.GetValues(src.GetType()); 44 | int j = Array.IndexOf(Arr, src) - 1; 45 | return (j < 0) ? Arr.Last() : Arr[j]; 46 | } 47 | 48 | private const string controlsCategory = "Controls"; 49 | private const string comfortCategory = "Comfort"; 50 | private const string playerBodyCategory = "Player Body"; 51 | private const string renderingCategory = "Rendering"; 52 | 53 | public static ConfigFile Config { get; private set; } 54 | public static ConfigEntry SnapTurning { get; private set; } 55 | public static ConfigEntry ShowLegs { get; private set; } 56 | public static ConfigEntry RoomScaleBodyPosition { get; private set; } 57 | public static ConfigEntry Teleport { get; private set; } 58 | public static ConfigEntry FixedCameraDuringAnimations { get; private set; } 59 | public static ConfigEntry LeftHandedMode { get; private set; } 60 | public static ConfigEntry ShowLaserPointer { get; private set; } 61 | public static ConfigEntry SwapSticks { get; private set; } 62 | public static ConfigEntry ControllerBasedMovementDirection { get; private set; } 63 | public static ConfigEntry EnableHeadBob { get; private set; } 64 | public static ConfigEntry EnableParticles { get; private set; } 65 | 66 | //public static ConfigEntry WorldScale { get; private set; } 67 | public static float WorldScale = 3.5f; 68 | public static ConfigEntry HeightOffset { get; private set; } 69 | public static ConfigEntry VelocityTrigger { get; private set; } 70 | public static ConfigEntry AngularVelocityTrigger { get; private set; } 71 | public static ConfigEntry SnapTurnAngle { get; private set; } 72 | public static ConfigEntry SmoothRotationSpeed { get; private set; } 73 | public static ConfigEntry ShowLegacySteamVRHands { get; private set; } 74 | 75 | public static void SetUp(ConfigFile config) 76 | { 77 | SetUpResolution(); 78 | 79 | Config = config; 80 | SnapTurning = config.Bind(comfortCategory, "SnapTurning", true, 81 | "Snap turning|Enabled: snap turning. Disabled: smooth turning."); 82 | SnapTurnAngle = config.Bind(comfortCategory, "SnapTurnAngle", SnapTurnAngleOption.Angle45, 83 | "Snap turn angle|How much to turn when snap turning is enabled."); 84 | SmoothRotationSpeed = config.Bind(comfortCategory, "SmoothRotationSpeed", SmoothRotationSpeedOption.Default, 85 | "Smooth rotation speed|How fast to turn when snap turning is disabled."); 86 | Teleport = config.Bind(comfortCategory, "Teleport", false, 87 | "Fixed camera while moving|\"Teleport\" locomotion. Camera stays still while player moves."); 88 | FixedCameraDuringAnimations = config.Bind(comfortCategory, "FixedCameraDuringAnimations", false, 89 | "Fixed camera during animations|Camera stays still during some larger animations."); 90 | RoomScaleBodyPosition = config.Bind(playerBodyCategory, "RoomScaleBodyPosition", true, 91 | "Make player body follow headset position|Disabling prevents drifting, but you'll need to occasionally recenter manually in the pause menu."); 92 | ControllerBasedMovementDirection = config.Bind(controlsCategory, "ControllerBasedMovementDirection", false, 93 | "Controller-based movement direction|Enabled: controller-based direction. Disabled: head-based direction."); 94 | EnableHeadBob = config.Bind(comfortCategory, "EnableHeadBob", false, 95 | "Enable to turn on Headbob (default: off)"); 96 | EnableParticles = config.Bind(comfortCategory, "EnableParticles", true, 97 | "Turn on Dust and Particles (default: on)"); 98 | LeftHandedMode = config.Bind(controlsCategory, "LeftHandedMode", false, 99 | "Left handed mode."); 100 | ShowLaserPointer = config.Bind(controlsCategory, "ShowLaserPointer", false, 101 | "Show the laser pointer for offhand interactions"); 102 | SwapSticks = config.Bind(controlsCategory, "SwapSticks", false, 103 | "Swap movement / rotation sticks|Swaps controller sticks, independently of handedness."); 104 | /*WorldScale = config.Bind(renderingCategory, "WorldScale", 3.5f, 105 | "World Scale. Increase for World/Objects to look smaller|Decrease for World/Objects to look bigger");*/ 106 | HeightOffset = config.Bind(renderingCategory, "HeightOffset", 0.0f, 107 | "Height Offset. Increase to be taller and vice versa"); 108 | VelocityTrigger = config.Bind(controlsCategory, "VelocityTrigger", 10.0f, 109 | "Melee Weapon Velocity Trigger. Increase to require more movement before hit"); 110 | AngularVelocityTrigger = config.Bind(controlsCategory, "AngularVelocityTrigger", 10.0f, 111 | "Melee Weapon Angular Velocity Trigger. Increase to require more movement before hit"); 112 | ShowLegacySteamVRHands = config.Bind(playerBodyCategory, "ShowLegacySteamVRHands", false, 113 | "Set to 'true' to use the old SteamVR dark hands (as seen in early trailers). Must be set before launching the game"); 114 | } 115 | 116 | public static string GetSnapTurnAngle() 117 | { 118 | string angle = SnapTurnAngle.Value.ToString(); 119 | angle = angle.Replace("Angle", ""); 120 | return angle; 121 | } 122 | 123 | public static void UpdateSnapTurnAngle(bool higher) 124 | { 125 | if(higher) 126 | SnapTurnAngle.Value = SnapTurnAngle.Value.Next(); 127 | else 128 | SnapTurnAngle.Value = SnapTurnAngle.Value.Previous(); 129 | } 130 | 131 | public static void UpdateSmoothTurnSpeed(bool higher) 132 | { 133 | if (higher) 134 | SmoothRotationSpeed.Value = SmoothRotationSpeed.Value.Next(); 135 | else 136 | SmoothRotationSpeed.Value = SmoothRotationSpeed.Value.Previous(); 137 | } 138 | 139 | /*public static void UpdateWorldScale(bool higher) 140 | { 141 | if (higher) 142 | WorldScale.Value += 0.5f; 143 | else 144 | { 145 | if(WorldScale.Value > 0.5f) 146 | WorldScale.Value -= 0.5f; 147 | } 148 | 149 | }*/ 150 | 151 | public static void UpdateHeightOffset(bool higher) 152 | { 153 | if (higher) 154 | HeightOffset.Value += 0.1f; 155 | else 156 | HeightOffset.Value -= 0.1f; 157 | } 158 | 159 | public static void UpdateVelocityTrigger(bool higher) 160 | { 161 | if (higher) 162 | VelocityTrigger.Value += 0.1f; 163 | else 164 | VelocityTrigger.Value -= 0.1f; 165 | } 166 | 167 | public static void UpdateAngularVelocityTrigger(bool higher) 168 | { 169 | if (higher) 170 | AngularVelocityTrigger.Value += 1.0f; 171 | else 172 | AngularVelocityTrigger.Value -= 1.0f; 173 | } 174 | 175 | public static void UpdateLeftHandedMode() 176 | { 177 | VRPlayerController vrPlayerController = VrCore.instance.GetVRPlayerController(); 178 | if(vrPlayerController) 179 | { 180 | vrPlayerController.UpdateLeftHandedMode(); 181 | } 182 | } 183 | 184 | private static void SetUpResolution() 185 | { 186 | Screen.SetResolution(1920, 1080, false); 187 | } 188 | } -------------------------------------------------------------------------------- /BendyVR_5/src/UI/CanvasToWorldSpace.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using TMG.UI; 7 | using UnityEngine; 8 | 9 | namespace BendyVR_5.UI 10 | { 11 | public static class CanvasToWorldSpace 12 | { 13 | public static void MoveToCameraSpace(BaseUIController __instance, float planeDistance = 1.0f) 14 | { 15 | Logs.WriteInfo($"Working with object ({__instance.name})"); 16 | var canvas = __instance.GetComponent(); 17 | if (!canvas) 18 | { 19 | Logs.WriteError($"No Canvas Found in Object ({__instance.name})"); 20 | return; 21 | } 22 | if (canvas.renderMode == RenderMode.ScreenSpaceCamera) 23 | { 24 | Logs.WriteWarning($"Canvas already has render mode ({canvas.renderMode.ToString()})"); 25 | canvas.planeDistance = planeDistance; 26 | return; 27 | } 28 | canvas.renderMode = RenderMode.ScreenSpaceCamera; 29 | canvas.planeDistance = planeDistance; 30 | Logs.WriteInfo($"Canvas Should be set to Screen Space Camera ({__instance.name})"); 31 | } 32 | 33 | public static void MoveToWorldSpace(BaseUIController __instance, float scale = 1.0f) 34 | { 35 | try 36 | { 37 | Logs.WriteInfo($"Working with object ({__instance.name})"); 38 | var canvas = __instance.GetComponent(); 39 | if (!canvas) 40 | { 41 | Logs.WriteError($"No Canvas Found in Object ({__instance.name})"); 42 | return; 43 | } 44 | if (canvas.renderMode == RenderMode.WorldSpace) 45 | { 46 | Logs.WriteWarning($"Canvas already has render mode ({canvas.renderMode.ToString()})"); 47 | return; 48 | } 49 | canvas.renderMode = RenderMode.WorldSpace; 50 | Logs.WriteInfo($"Canvas Should be set to World Space ({__instance.name})"); 51 | 52 | //Ensure Scale is Correct 53 | __instance.transform.position = new Vector3(0, 0, 0); 54 | __instance.transform.localScale = new Vector3(scale, scale, scale); 55 | __instance.transform.localRotation = Quaternion.identity; 56 | __instance.transform.localPosition = Vector3.zero; 57 | 58 | // Canvases with graphic raycasters are the ones that receive click events. 59 | // Those need to be handled differently, with colliders for the laser ray. 60 | /* 61 | * if (canvas.GetComponent()) 62 | AttachedUi.Create(canvas, StageInstance.GetInteractiveUiTarget(), 0.002f); 63 | else 64 | AttachedUi.Create(canvas, StageInstance.GetStaticUiTarget(), 0.00045f); 65 | */ 66 | } 67 | catch (Exception exception) 68 | { 69 | Logs.WriteWarning($"Failed to move canvas to world space ({__instance.name}): {exception}"); 70 | } 71 | } 72 | 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /BendyVR_5/src/UI/Patches/CanvasToWorldSpacePatches.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HarmonyLib; 3 | using BendyVR_5.Helpers; 4 | using UnityEngine; 5 | using UnityEngine.EventSystems; 6 | using UnityEngine.UI; 7 | using BendyVR_5.src; 8 | 9 | namespace BendyVR_5.UI.Patches; 10 | 11 | [HarmonyPatch] 12 | public class CanvasToWorldSpacePatches : BendyVRPatch 13 | { 14 | private static readonly string[] canvasesToDisable = 15 | { 16 | "BlackBars", // Cinematic black bars. 17 | "Camera" // Disposable camera. 18 | }; 19 | 20 | private static readonly string[] canvasesToIgnore = 21 | { 22 | "com.sinai.unityexplorer_Root", // UnityExplorer. 23 | "com.sinai.unityexplorer.MouseInspector_Root", // UnityExplorer. 24 | "ExplorerCanvas" 25 | }; 26 | 27 | [HarmonyPrefix] 28 | [HarmonyPatch(typeof(UIBehaviour), "Awake")] 29 | private static void UIBehaviourAwake(UIBehaviour __instance) 30 | { 31 | LayerHelper.SetLayer(__instance, GameLayer.UI); 32 | } 33 | 34 | private static bool IsCanvasToIgnore(string canvasName) 35 | { 36 | foreach (var s in canvasesToIgnore) 37 | if (Equals(s, canvasName)) 38 | return true; 39 | return false; 40 | } 41 | 42 | private static bool IsCanvasToDisable(string canvasName) 43 | { 44 | foreach (var s in canvasesToDisable) 45 | if (Equals(s, canvasName)) 46 | return true; 47 | return false; 48 | } 49 | } -------------------------------------------------------------------------------- /BendyVR_5/src/UI/Patches/MainMenuPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using HarmonyLib; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | using BendyVR_5.Helpers; 6 | using System; 7 | using TMG.UI; 8 | using InControl; 9 | using TMG.Controls; 10 | using TMG.UI.Controls; 11 | using BendyVR_5.Assets; 12 | using BendyVR_5.Stage; 13 | using BendyVR_5.src; 14 | 15 | namespace BendyVR_5.UI.Patches; 16 | 17 | [HarmonyPatch] 18 | public class MainMenuPatches : BendyVRPatch 19 | { 20 | // These are all overlays that only made sense in pancake mode. 21 | private static readonly string[] objectsToDisable = 22 | { 23 | "Particles" 24 | }; 25 | 26 | //This removes the horrible gaze thing from the menus 27 | //TODO possibly change this to laser later - not really necessary 28 | [HarmonyPostfix] 29 | /*[HarmonyPatch(typeof(TitleScreenController), nameof(TitleScreenController.InitController))] 30 | [HarmonyPatch(typeof(OptionsMenuController), nameof(OptionsMenuController.InitController))]*/ 31 | [HarmonyPatch(typeof(BaseUIController), nameof(BaseUIController.InitController))] 32 | private static void RemoveCustomInput(BaseUIController __instance) 33 | { 34 | GraphicRaycaster gr = __instance.gameObject.GetComponent(); 35 | if (gr != null) 36 | gr.enabled = false; 37 | } 38 | 39 | [HarmonyPostfix] 40 | [HarmonyPatch(typeof(OptionsMenuController), nameof(OptionsMenuController.InitController))] 41 | private static void RemoveCustomInput(TitleScreenController __instance) 42 | { 43 | __instance.gameObject.GetComponent().enabled = false; 44 | } 45 | 46 | [HarmonyPostfix] 47 | [HarmonyPatch(typeof(TitleScreenController), nameof(TitleScreenController.InitController))] 48 | private static void DisableUnnecessaryMainMenuObjects(TitleScreenController __instance) 49 | { 50 | foreach (Transform child in __instance.transform) 51 | if (objectsToDisable.Contains(child.name)) 52 | child.gameObject.SetActive(false); 53 | } 54 | 55 | [HarmonyPostfix] 56 | [HarmonyPatch(typeof(TitleScreenController), nameof(TitleScreenController.InitController))] 57 | private static void DebugControllers(TitleScreenController __instance) 58 | { 59 | Logs.WriteInfo("Game Manager Has Controller: " + GameManager.Instance.HasController.ToString()); 60 | Logs.WriteInfo("InputManager Device Count: " + InputManager.Devices.Count.ToString()); 61 | 62 | 63 | //Lets try to change the background 64 | var uiparent = GameObject.Find("[UI MANAGER]"); 65 | if (uiparent) 66 | { 67 | Logs.WriteWarning("Found: " + uiparent.name); 68 | var background = GameObject.Find("Visuals/BG/BG"); 69 | if (background) 70 | { 71 | Logs.WriteWarning("Found: " + background.name); 72 | GameObject.Find("Visuals/BG/LightCookie").SetActive(false); 73 | Logs.WriteWarning("Turned off Light Cookie"); 74 | GameObject.Find("Visuals/BG/Frame").SetActive(false); 75 | Logs.WriteWarning("Turned off Frame"); 76 | //background.gameObject.SetActive(true); 77 | var image = background.GetComponent(); 78 | if (image) 79 | { 80 | Logs.WriteWarning("Found Image"); 81 | image.sprite = VrAssetLoader.MenuBG; 82 | } 83 | } 84 | } 85 | 86 | /*image.texture = null; 87 | image.color = new Color(0, 0, 0, 0.75f); 88 | if (image.transform.localPosition.z == 0) image.transform.localPosition += Vector3.forward * 50;*/ 89 | } 90 | 91 | [HarmonyPostfix] 92 | [HarmonyPatch(typeof(BaseUIController), nameof(BaseUIController.InitController))] 93 | private static void CorrectSettingsCanvas(BaseUIController __instance) 94 | { 95 | if (__instance is ScreenBlockerController) 96 | { 97 | CanvasToWorldSpace.MoveToCameraSpace(__instance,1f); 98 | } 99 | else if (__instance is CH1ConclusionModalController) 100 | { 101 | CanvasToWorldSpace.MoveToCameraSpace(__instance, 2f); 102 | } 103 | else if (__instance is HurtBordersController) 104 | { 105 | CanvasToWorldSpace.MoveToCameraSpace(__instance,4f); 106 | } 107 | else 108 | { 109 | CanvasToWorldSpace.MoveToWorldSpace(__instance, 0.75f); 110 | } 111 | } 112 | 113 | [HarmonyPostfix] 114 | [HarmonyPatch(typeof(TitleScreenController), nameof(TitleScreenController.InitController))] 115 | private static void MoveStoreButton(TitleScreenController __instance) 116 | { 117 | __instance.m_StoreBtn.transform.localPosition = new Vector3(-700f, 405f,0f); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /BendyVR_5/src/UI/Patches/PauseMenuPatches.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using BendyVR_5.Helpers; 3 | using UnityEngine; 4 | using TMG.Controls; 5 | using BendyVR_5.Stage; 6 | 7 | namespace BendyVR_5.UI.Patches; 8 | 9 | [HarmonyPatch] 10 | public static class PauseMenuPatches 11 | { 12 | [HarmonyPrefix] 13 | [HarmonyPatch(typeof(GameMenuController), nameof(GameMenuController.Quit))] 14 | private static void NotifyQuit(GameMenuController __instance) 15 | { 16 | //VrCore.instance.quitTriggered = true; 17 | //TODO - What the hell is this doing? Need to debug the whole thing 18 | Application.Quit(); 19 | } 20 | 21 | 22 | } -------------------------------------------------------------------------------- /BendyVR_5/src/UI/Patches/SettingsMenuPatches.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using HarmonyLib; 3 | using UnityEngine; 4 | 5 | // Some of the available game settings don't go well with VR. 6 | // These patches force some settings to certain values to prevent VR funkyness. 7 | namespace BendyVR_5.UI.Patches; 8 | 9 | [HarmonyPatch] 10 | public class SettingsMenuPatches 11 | { 12 | [HarmonyPostfix] 13 | [HarmonyPatch(typeof(OptionsMenuController), nameof(OptionsMenuController.ShowAdvancedMenu))] 14 | private static void RepositionAdvanced(OptionsMenuController __instance) 15 | { 16 | var advanced = GameObject.Find("Visuals/AdvancedMenu"); 17 | Logs.WriteWarning("Found: " + advanced.name); 18 | RectTransform rt = advanced.GetComponent(); 19 | rt.position = new Vector3(0f, 150f, -260f); 20 | } 21 | } -------------------------------------------------------------------------------- /BendyVR_5/src/UI/Patches/TutorialPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using HarmonyLib; 3 | using TMPro; 4 | using BendyVR_5.Helpers; 5 | //using BendyVR_5.VrInput; 6 | using UnityEngine; 7 | 8 | namespace BendyVR_5.UI.Patches; 9 | 10 | /*[HarmonyPatch] 11 | public static class TutorialPatches 12 | { 13 | private static readonly Dictionary tutorialTextMap = new() 14 | { 15 | {"textRadio", $"Hold [{VirtualKey.Radio}] to activate radio."}, 16 | {"textRadio_select_dialog", $"[{VirtualKey.ScrollUpDown}] to select dialog."}, 17 | {"textUse_radio", $"Release [{VirtualKey.Radio}] to talk to Delilah."}, 18 | {"textInspect_object", "Look at hand to inspect objects."}, 19 | {"textInspect_object_move", ""}, 20 | { 21 | "textRadio_object", 22 | $"Aim with dominant hand and hold [{VirtualKey.Radio}] to talk about targeted object." 23 | }, 24 | {"textJournal_examine", "Look at hand to inspect journal."}, 25 | {"textJournal_stow", $"[{VirtualKey.StoreObject}] to keep journal."}, 26 | {"textCompass", $"Hold [{VirtualKey.ToolPicker}] to select compass from tool picker."}, 27 | {"textFlashlight", $"Hold [{VirtualKey.ToolPicker}] to select flashlight from tool picker."}, 28 | {"textMap", $"Hold [{VirtualKey.ToolPicker}] to select map from tool picker."}, 29 | {"textJog_toggle", $"Press [{VirtualKey.Jog}] to toggle jogging."}, 30 | {"textMantle", $"Press [{VirtualKey.LocomotionAction}] to climb over obstructions."}, 31 | {"textUse_object", $"Aim with dominant hand and press [{VirtualKey.Use}] to use objects."}, 32 | {"textInventory_open", $"Hold [{VirtualKey.ToolPicker}] to select notes inventory from the tool picker."}, 33 | {"textInventory_browse", "Use hand laser to select notes. Drag with laser to scroll."}, 34 | {"textInventory_read", $"[{VirtualKey.StoreObject}] to store note"}, 35 | {"textCamera", $"Hold [{VirtualKey.ToolPicker}] to select camera from tool picker."}, 36 | {"textCamera_picture", $"Press [{VirtualKey.Use}] to take a picture."}, 37 | {"textCamera_lower", $"Press [{VirtualKey.ToolPicker}] to lower camera."}, 38 | {"textWaveReceiver", $"Hold [{VirtualKey.ToolPicker}] to select wave receiver from tool picker."}, 39 | {"textRadio_concept", $"Hold [{VirtualKey.Radio}] to radio about current subject of interest."}, 40 | {"textRadio_heldobject", $"Hold [{VirtualKey.Radio}] to talk about currently held object."}, 41 | 42 | // There's no zooming in VR. Couldn't figure out an easy way to hide the whole tutorial box, 43 | // so I'm just showing the jogging tutorial instead. 44 | {"textZoom", $"Press [{VirtualKey.Jog}] to toggle jogging."}, 45 | 46 | // Unused tutorial text. 47 | {"Text", ""} 48 | }; 49 | 50 | [HarmonyPrefix] 51 | [HarmonyPatch(typeof(vgHudManager), nameof(vgHudManager.Awake))] 52 | private static void SetUpTutorials(vgHudManager __instance) 53 | { 54 | var tutorialObject = 55 | __instance.transform.Find( 56 | "uGUI Root/HUD/SafeZoner/BottomCenterGroup/TutorialPopup/TutorialPopupParent/TutorialObject"); 57 | 58 | Logs.WriteInfo($"Found {tutorialObject.childCount} tutorials"); 59 | foreach (Transform child in tutorialObject) 60 | { 61 | Logs.WriteInfo($"{child.name}: {child.GetComponent().text}"); 62 | tutorialTextMap.TryGetValue(child.name, out var tutorialString); 63 | if (tutorialString == null) 64 | { 65 | Logs.WriteError($"No tutorial text found for {child.name}"); 66 | continue; 67 | } 68 | 69 | child.GetComponent().text = tutorialString; 70 | } 71 | } 72 | }*/ -------------------------------------------------------------------------------- /BendyVR_5/src/VRCore/Patches/StagePatches.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using BendyVR_5.UI; 4 | using DG.Tweening; 5 | using HarmonyLib; 6 | using TMG.Core; 7 | using UnityEngine; 8 | using UnityEngine.VR; 9 | using UnityEngine.XR; 10 | 11 | namespace BendyVR_5.Stage.Patches; 12 | 13 | [HarmonyPatch] 14 | public class StagePatches : BendyVRPatch 15 | { 16 | private static GameManager gameManager; 17 | 18 | [HarmonyPrefix] 19 | [HarmonyPatch(typeof(InitializeGame), nameof(InitializeGame.InitPlayerSettings))] 20 | private static void CreateVRCore(InitializeGame __instance) 21 | { 22 | gameManager = __instance.m_GameManager; 23 | VrCore.Create(gameManager); 24 | } 25 | 26 | [HarmonyPostfix] 27 | [HarmonyPatch(typeof(PlayerController), nameof(PlayerController.Init))] 28 | public static void SetUpStagePlayer(PlayerController __instance) 29 | { 30 | // Getting camera manually because cameraController.camera isn't set up yet. 31 | //var camera = __instance.cameraController.GetComponentInChildren(); 32 | 33 | //First Turn off the tracking of the weapon camera 34 | XRDevice.DisableAutoXRCameraTracking(GameManager.Instance.GameCamera.WeaponCamera, true); 35 | 36 | //Also Turn Off tracking of the main camera 37 | //XRDevice.DisableAutoXRCameraTracking(GameManager.Instance.GameCamera.Camera, true); 38 | 39 | var camera = GameManager.Instance.GameCamera.Camera; 40 | Logs.WriteInfo("Setting Up VR Core (PlayerController Initialised)"); 41 | StageInstance.SetUp(camera, __instance); 42 | } 43 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VRCore/VrCore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using BendyVR_5.Debugging; 4 | using BendyVR_5.Helpers; 5 | using BendyVR_5.Player; 6 | using BendyVR_5.Settings; 7 | using BendyVR_5.src; 8 | using BendyVR_5.UI; 9 | using BendyVR_5.VrCamera; 10 | using BendyVR_5.VrInput; 11 | using BendyVR_5.VrInput.ActionInputs; 12 | using UnityEngine; 13 | using UnityEngine.SceneManagement; 14 | using UnityEngine.XR; 15 | 16 | namespace BendyVR_5.Stage; 17 | 18 | public class VrCore : MonoBehaviour 19 | { 20 | public static VrCore instance; 21 | private static GameManager m_gameManager; 22 | 23 | private static readonly string[] fallbackCameraTagSkipScenes = {"Main", "PreLoad"}; 24 | private BindingsManager bindingsManager; 25 | private VRPlayerController vrPlayerController; 26 | 27 | private VRCameraManager cameraManager; 28 | private FadeOverlay fadeOverlay; 29 | private Camera mainCamera; 30 | 31 | private VeryLateUpdateManager veryLateUpdateManager; 32 | 33 | //private LivManager livManager; // GB This is for mixed motion capture 34 | 35 | public static void Create(GameManager gm_parent) 36 | { 37 | if (instance) return; 38 | 39 | m_gameManager = gm_parent; 40 | 41 | var stageParent = new GameObject("VrCoreParent") 42 | { 43 | //transform = {parent = parent} 44 | }; 45 | 46 | DontDestroyOnLoad(stageParent); 47 | instance = new GameObject("VrCore").AddComponent(); 48 | instance.transform.SetParent(stageParent.transform, false); 49 | instance.vrPlayerController = VRPlayerController.Create(instance); 50 | instance.veryLateUpdateManager = VeryLateUpdateManager.Create(instance); 51 | instance.bindingsManager = BindingsManager.Create(instance); 52 | 53 | BendyVRPatch.SetStage(instance); 54 | } 55 | 56 | public float GetAttackVelocity() 57 | { 58 | return vrPlayerController.velocityVectorLength; 59 | } 60 | public float GetAttackAngularVelocity() 61 | { 62 | return vrPlayerController.angularVelocityVectorLength; 63 | } 64 | 65 | public void SetUp(Camera camera, PlayerController playerController) 66 | { 67 | mainCamera = camera; 68 | var playerTransform = playerController ? playerController.transform : null; 69 | vrPlayerController.SetUp(playerController); 70 | 71 | // If the camera starts with an offset position, the tracking will always be incorrect. 72 | // So I disable VR, reset the camera position, and then enable VR again. 73 | XRSettings.enabled = false; 74 | 75 | //Create something above both CameraContainer... Then Move CameraContainer and Camera itself to that. Then FakeParent Camera to CameraContainer 76 | //(Since CameraContainer is used for interactions - it actually isn't anymore so don't even know if I need this) 77 | 78 | 79 | 80 | //playerController.transform.SetParent(mRoomScaleDamper,false); 81 | //playerController.transform.localPosition = new Vector3(0f, 0f, 0f); 82 | //playerController.m_HeadContainer.SetParent(mRoomScaleDamper); 83 | //playerController.m_HandContainer.SetParent(mRoomScaleDamper); 84 | //playerController.transform.localPosition = new Vector3(0f,0f,0f); 85 | //playerController.m_HeadContainer.localPosition = new Vector3(0f, 0f, playerController.transform.localPosition.z); 86 | //playerController.m_HandContainer.localPosition = new Vector3(0f, 0f, playerController.transform.localPosition.z); 87 | //TODO Feet 88 | 89 | //Room Scale - Create a movement buffer above the PlayerController and DeltaTransform that 90 | //TODO -> Only do X and Y 91 | //mRoomScaleDamper = new GameObject("RoomScaleDamper").transform; 92 | //playerController.transform.parent = mRoomScaleDamper; 93 | 94 | //Also Newly Set the Camera to also be below VrCameraParent 95 | //GameManager.Instance.GameCamera.transform.SetParent(mRoomScaleDamper); 96 | 97 | //Need to figure out roomscale.... ideally move the playercontroller position to match camera position and headcontainer to be the opposite 98 | //FakeParenting.Create(playerController.transform, GameManager.Instance.GameCamera.transform, FakeParenting.UpdateType.LateUpdate, FakeParenting.TransformType.All); 99 | //FakeParenting.Create(mRoomScaleDamper, GameManager.Instance.GameCamera.transform, FakeParenting.UpdateType.LateUpdate, FakeParenting.TransformType.DeltaInverseTransformOnly); 100 | //FakeParenting.Create(playerController.m_HeadContainer, GameManager.Instance.GameCamera.transform, FakeParenting.UpdateType.LateUpdate, FakeParenting.TransformType.DeltaInverseTransformOnly); 101 | 102 | 103 | //Set Gamecamera planes 104 | GameManager.Instance.GameCamera.Camera.nearClipPlane = 0.01f; 105 | 106 | //Set Camera World Scale (Move Later) 107 | UpdateWorldScale(); 108 | ResetHeight(); 109 | //VrSettings.WorldScale.SettingChanged += UpdateWorldScaleRealTime; 110 | VrSettings.HeightOffset.SettingChanged += UpdateWorldScaleRealTime; 111 | 112 | XRSettings.enabled = true; 113 | 114 | //cameraManager.SetUp(mainCamera, playerTransform); 115 | //limbManager.SetUp(playerController, GameManager.Instance.GameCamera.Camera); 116 | //interactiveUiTarget.SetUp(nextCamera); 117 | //staticUiTarget.SetUp(nextCamera); 118 | //teleportController.SetUp(playerController); 119 | //FadeOverlay.Create(GameManager.Instance.GameCamera.Camera); 120 | veryLateUpdateManager.SetUp(GameManager.Instance.GameCamera.Camera); 121 | //turningController.SetUp(playerController); 122 | //roomScaleBodyTransform.SetUp(playerController); 123 | //bodyRendererManager.SetUp(playerController); 124 | //livManager.SetUp(nextCamera); 125 | } 126 | 127 | internal VRPlayerController GetVRPlayerController() 128 | { 129 | return vrPlayerController; 130 | } 131 | 132 | private void UpdateWorldScaleRealTime(object sender, EventArgs e) 133 | { 134 | UpdateWorldScale(); 135 | ResetHeight(); 136 | } 137 | 138 | public void UpdateWorldScale() 139 | { 140 | float scale = VrSettings.WorldScale; 141 | //GameManager.Instance.GameCamera.transform.localScale = new Vector3(scale, scale, scale); 142 | if (vrPlayerController.mNewCameraParent) 143 | vrPlayerController.mNewCameraParent.localScale = new Vector3(scale, scale, scale); 144 | else 145 | Logs.WriteError("mNewCameraParent does not exist! (UpdateWorldScale)"); 146 | 147 | if(GameManager.Instance.Player.m_HandContainer) 148 | GameManager.Instance.Player.m_HandContainer.localScale = new Vector3(scale, scale, scale); 149 | else 150 | Logs.WriteError("m_HandContainer does not exist! (UpdateWorldScale)"); 151 | } 152 | 153 | private void ResetHeight() 154 | { 155 | /*float scale = VrSettings.WorldScale.Value; 156 | float offset = (-1.5f * scale) + 0.7f; 157 | offset += VrSettings.HeightOffset.Value; 158 | 159 | vrPlayerController.mNewCameraParent.localPosition = new Vector3(0, offset, 0); 160 | 161 | GameManager.Instance.Player.m_HandContainer.localPosition = new Vector3(0, 0, 0); 162 | //Measure the difference between VRCameraParent and Hand Container (Absolute) -> Thats the new Hand Container offset - Don't ask me to explain it 163 | float handContainerOffset = vrPlayerController.mNewCameraParent.position.y - GameManager.Instance.Player.m_HandContainer.position.y; 164 | GameManager.Instance.Player.m_HandContainer.localPosition = new Vector3(0, handContainerOffset, 0); 165 | 166 | Logs.WriteInfo("Scale = " + scale); 167 | Logs.WriteInfo("Hand Offset = " + handContainerOffset); 168 | Logs.WriteInfo("VrCameraParent Y = " + vrPlayerController.mNewCameraParent.localPosition.y);*/ 169 | } 170 | 171 | 172 | private void OnDisable() 173 | { 174 | throw new Exception( 175 | "The VR Stage is being disabled. This should never happen. Check the call stack of this error to find the culprit."); 176 | } 177 | 178 | public Camera GetMainCamera() 179 | { 180 | return mainCamera; 181 | } 182 | 183 | public void RecenterPosition(bool recenterVertically = false) 184 | { 185 | cameraManager.RecenterPosition(recenterVertically); 186 | } 187 | 188 | public void RecenterRotation() 189 | { 190 | cameraManager.RecenterRotation(); 191 | } 192 | 193 | public void Recenter() 194 | { 195 | RecenterPosition(true); 196 | RecenterRotation(); 197 | } 198 | 199 | public void FadeToBlack() 200 | { 201 | FadeOverlay.StartFade(Color.black, FadeOverlay.Duration); 202 | } 203 | 204 | public void FadeToClear() 205 | { 206 | FadeOverlay.StartFade(Color.clear, FadeOverlay.Duration); 207 | } 208 | 209 | public IActionInput GetInputAction(string virtualKey) 210 | { 211 | if (!bindingsManager) return null; 212 | bindingsManager.ActionMap.TryGetValue(virtualKey, out var value); 213 | return value; 214 | } 215 | 216 | public float GetInputValue(string virtualKey) 217 | { 218 | if (!bindingsManager) return 0; 219 | return bindingsManager.GetValue(virtualKey); 220 | } 221 | 222 | public bool GetInputUp(string virtualKey) 223 | { 224 | return bindingsManager && bindingsManager.GetUp(virtualKey); 225 | } 226 | 227 | public bool GetInputDown(string virtualKey) 228 | { 229 | return bindingsManager && bindingsManager.GetDown(virtualKey); 230 | } 231 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VeryLateUpdateManager.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | //using TwoForksVr.PlayerBody; 3 | using BendyVR_5.Stage; 4 | using UnityEngine; 5 | 6 | namespace BendyVR_5.src; 7 | 8 | // This manager handles some methods that need to run as late as possible, after every other update. 9 | // They often need to run in a specific order, which is also defined here. 10 | public class VeryLateUpdateManager : MonoBehaviour 11 | { 12 | private Camera camera; 13 | 14 | public static VeryLateUpdateManager Create(VrCore stage) 15 | { 16 | return stage.gameObject.AddComponent(); 17 | } 18 | 19 | public void SetUp(Camera activeCamera) 20 | { 21 | camera = activeCamera; 22 | } 23 | 24 | private void Awake() 25 | { 26 | Camera.onPreCull += HandlePreCull; 27 | } 28 | 29 | private void OnDestroy() 30 | { 31 | Camera.onPreCull -= HandlePreCull; 32 | } 33 | 34 | private void HandlePreCull(Camera preCullCamera) 35 | { 36 | if (preCullCamera != camera) return; 37 | 38 | //BendyVRBehavior.InvokeVeryLateUpdate(); 39 | BendyVRBehavior.InvokeVeryLateUpdate(); 40 | BendyVRBehavior.InvokeVeryLateUpdate(); 41 | } 42 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrCamera/FadeOverlay.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Assets; 2 | using UnityEngine; 3 | using Valve.VR; 4 | 5 | namespace BendyVR_5.VrCamera; 6 | 7 | // TODO clean this up. This was adapted from SteamVR code and it has some unnecessary stuff. 8 | public class FadeOverlay : MonoBehaviour 9 | { 10 | public const float Duration = 0.1f; 11 | private static Material fadeMaterial; 12 | private static int fadeMaterialColorID = -1; 13 | 14 | private Color currentColor = new(0, 0, 0, 0); // default starting color: black and fully transparent 15 | 16 | // the delta-color is basically the "speed / second" at which the current color should change 17 | private Color deltaColor = new(0, 0, 0, 0); 18 | 19 | private Color targetColor = new(0, 0, 0, 0); // default target color: black and fully transparent 20 | 21 | public static void Create(Camera camera) 22 | { 23 | camera.gameObject.AddComponent(); 24 | } 25 | 26 | private void OnEnable() 27 | { 28 | if (fadeMaterial == null) 29 | { 30 | fadeMaterial = new Material(VrAssetLoader.FadeShader); 31 | fadeMaterialColorID = Shader.PropertyToID("fadeColor"); 32 | } 33 | 34 | SteamVR_Events.Fade.Listen(OnStartFade); 35 | SteamVR_Events.FadeReady.Send(); 36 | } 37 | 38 | private void OnDisable() 39 | { 40 | SteamVR_Events.Fade.Remove(OnStartFade); 41 | } 42 | 43 | private void OnPostRender() 44 | { 45 | if (currentColor != targetColor) 46 | { 47 | // if the difference between the current alpha and the desired alpha is smaller than delta-alpha * deltaTime, then we're pretty much done fading: 48 | if (Mathf.Abs(currentColor.a - targetColor.a) < Mathf.Abs(deltaColor.a) * Time.deltaTime) 49 | { 50 | currentColor = targetColor; 51 | deltaColor = new Color(0, 0, 0, 0); 52 | } 53 | else 54 | { 55 | currentColor += deltaColor * Time.deltaTime; 56 | } 57 | } 58 | 59 | if (currentColor.a > 0 && fadeMaterial) 60 | { 61 | fadeMaterial.SetColor(fadeMaterialColorID, currentColor); 62 | fadeMaterial.SetPass(0); 63 | GL.Begin(GL.QUADS); 64 | 65 | GL.Vertex3(-1, -1, 0); 66 | GL.Vertex3(1, -1, 0); 67 | GL.Vertex3(1, 1, 0); 68 | GL.Vertex3(-1, 1, 0); 69 | GL.End(); 70 | } 71 | } 72 | 73 | public static void StartFade(Color newColor, float duration, bool fadeOverlay = false) 74 | { 75 | SteamVR_Events.Fade.Send(newColor, duration, fadeOverlay); 76 | } 77 | 78 | public void OnStartFade(Color newColor, float duration, bool fadeOverlay) 79 | { 80 | if (duration > 0.0f) 81 | { 82 | targetColor = newColor; 83 | deltaColor = (targetColor - currentColor) / duration; 84 | } 85 | else 86 | { 87 | currentColor = newColor; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrCamera/Patches/GameCameraPatches.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.Stage; 3 | using DG.Tweening; 4 | using HarmonyLib; 5 | using S13Audio; 6 | using UnityEngine; 7 | using UnityEngine.PostProcessing; 8 | using TMG.Core; 9 | using System; 10 | using BendyVR_5.src; 11 | using BendyVR_5.Settings; 12 | 13 | namespace BendyVR_5.VrCamera.Patches; 14 | 15 | [HarmonyPatch] 16 | public class GameCameraPatches : BendyVRPatch 17 | { 18 | private static bool isDone; 19 | 20 | [HarmonyPostfix] 21 | [HarmonyPatch(typeof(GameManager), nameof(GameManager.InitChapter1))] 22 | [HarmonyPatch(typeof(GameManager), nameof(GameManager.InitChapter2))] 23 | [HarmonyPatch(typeof(GameManager), nameof(GameManager.InitChapter3))] 24 | [HarmonyPatch(typeof(GameManager), nameof(GameManager.InitChapter4))] 25 | [HarmonyPatch(typeof(GameManager), nameof(GameManager.InitChapter5))] 26 | private static void TurnOffOcclusionMeshes(GameManager __instance) 27 | { 28 | VrCore.instance.GetVRPlayerController().inLevel = true; 29 | Logs.WriteInfo("Chapter " + __instance.CurrentChapter.name + " loaded"); 30 | //Loop through the whole scene and find mesh renderers 31 | var foundRenderers = Resources.FindObjectsOfTypeAll(typeof(MeshRenderer)); 32 | foreach (MeshRenderer meshRenderer in foundRenderers) 33 | { 34 | if (meshRenderer.name.ToLower().Contains("ink")) 35 | { 36 | meshRenderer.allowOcclusionWhenDynamic = false; 37 | Logs.WriteInfo("Ink Fix: " + meshRenderer.name); 38 | } 39 | } 40 | } 41 | 42 | [HarmonyPrefix] 43 | [HarmonyPatch(typeof(GameCamera), nameof(GameCamera.ExitFreeRoamCam))] 44 | public static bool VRExitFreeRoamCam(GameCamera __instance) 45 | { 46 | VrCore.instance.GetVRPlayerController().ExitFreeRoam(); 47 | return false; 48 | } 49 | 50 | [HarmonyPrefix] 51 | [HarmonyPatch(typeof(GameCamera), nameof(GameCamera.InitializeFreeRoamCam))] 52 | public static bool VRInitializeFreeRoamCam(ref Transform __result) 53 | { 54 | __result = VrCore.instance.GetVRPlayerController().InitializeFreeRoam(); 55 | return false; 56 | } 57 | 58 | [HarmonyPrefix] 59 | [HarmonyPatch(typeof(LittleMiracleStationController), nameof(LittleMiracleStationController.HandleDoorInteractableOnInteracted))] 60 | private static bool MiracleStationEntry(LittleMiracleStationController __instance) 61 | { 62 | GameManager.Instance.ShowScreenBlocker(0.3f); 63 | return true; 64 | } 65 | 66 | [HarmonyPrefix] 67 | [HarmonyPatch(typeof(LittleMiracleStationController), nameof(LittleMiracleStationController.HandleEntranceOnComplete))] 68 | private static void TurnOffHands() 69 | { 70 | Transform freeRoamCam = GameManager.Instance.GameCamera.FreeRoamCam; 71 | //Check we don't already have the offset (so we don't create one million 543 thousand game objects) 72 | Transform cameraOffset = freeRoamCam.Find("MiracleCameraOffset"); 73 | if (cameraOffset == null) 74 | cameraOffset = new GameObject("MiracleCameraOffset").transform; 75 | cameraOffset.SetParent(freeRoamCam); 76 | cameraOffset.localRotation = Quaternion.identity; 77 | //cameraOffset.localPosition = new Vector3(0f,-GameManager.Instance.GameCamera.Camera.transform.localPosition.y, 0f); 78 | cameraOffset.localPosition = -GameManager.Instance.GameCamera.Camera.transform.localPosition; 79 | 80 | GameManager.Instance.GameCamera.CameraContainer.SetParent(freeRoamCam); 81 | GameManager.Instance.GameCamera.CameraContainer.localScale = Vector3.one; 82 | GameManager.Instance.GameCamera.Camera.transform.SetParent(cameraOffset); 83 | VrCore.instance.GetVRPlayerController().inFreeRoam = true; 84 | VrCore.instance.GetVRPlayerController().mDominantHand.SetParent(cameraOffset); 85 | VrCore.instance.GetVRPlayerController().mNonDominantHand.SetParent(cameraOffset); 86 | 87 | //Removing Follow 88 | VrCore.instance.GetVRPlayerController().RemoveCameraFollow(); 89 | 90 | //GB New also need to move the camera there (and the hands) 91 | Logs.WriteWarning("Turning Off Both hands"); 92 | VrCore.instance.GetVRPlayerController().TurnOffBothHands(); 93 | GameManager.Instance.HideScreenBlocker(0f); 94 | } 95 | 96 | 97 | [HarmonyPostfix] 98 | [HarmonyPatch(typeof(LittleMiracleStationController), nameof(LittleMiracleStationController.HandleExitOnComplete))] 99 | private static void MiracleStationExit(LittleMiracleStationController __instance) 100 | { 101 | Logs.WriteWarning("EXITING MIRACLE STATION"); 102 | VrCore vrCore = VrCore.instance; 103 | vrCore.GetVRPlayerController().SetupCameraHierarchy(); 104 | vrCore.GetVRPlayerController().SetupCameraFollow(); 105 | vrCore.GetVRPlayerController().ParentHands(); 106 | if (GameManager.Instance.Player.WeaponGameObject == null) 107 | VrCore.instance.GetVRPlayerController().TurnOnBothHands(); 108 | else 109 | VrCore.instance.GetVRPlayerController().TurnOnNonDominantHand(); 110 | VrCore.instance.GetVRPlayerController().inFreeRoam = false; 111 | } 112 | 113 | [HarmonyPrefix] 114 | [HarmonyPatch(typeof(CameraFOV), nameof(CameraFOV.SetFOV))] 115 | [HarmonyPatch(typeof(CameraFOV), nameof(CameraFOV.DOFov))] 116 | [HarmonyPatch(typeof(CameraFOV), nameof(CameraFOV.UpdateVOD))] 117 | private static bool OverrideFOV() 118 | { 119 | return false; 120 | } 121 | 122 | [HarmonyPrefix] 123 | [HarmonyPatch(typeof(FirstPersonHeadBob), nameof(FirstPersonHeadBob.UpdateCameraPosition))] 124 | private static bool RemoveHeadBob() 125 | { 126 | return VrSettings.EnableHeadBob.Value; 127 | } 128 | 129 | [HarmonyPrefix] 130 | [HarmonyPatch(typeof(CameraMovements), nameof(CameraMovements.Sway))] 131 | private static bool RemoveSway() 132 | { 133 | return false; 134 | } 135 | 136 | [HarmonyPrefix] 137 | [HarmonyPatch(typeof(FirstPersonHeadBob), nameof(FirstPersonHeadBob.SetActive))] 138 | private static bool DeactivateHeadBob(FirstPersonHeadBob __instance) 139 | { 140 | if (!VrSettings.EnableHeadBob.Value) 141 | { 142 | __instance.m_Active = false; 143 | __instance.m_EnableJumpBob = false; 144 | return false; 145 | } 146 | return true; 147 | } 148 | 149 | //Effect glitches 150 | [HarmonyPrefix] 151 | [HarmonyPatch(typeof(LightFlicker), nameof(LightFlicker.Update))] 152 | private static bool TurnOffLightFlicker(LightFlicker __instance) 153 | { 154 | if(!__instance.m_IsOff) 155 | { 156 | __instance.TurnOff(); 157 | } 158 | return false; 159 | } 160 | 161 | [HarmonyPostfix] 162 | [HarmonyPatch(typeof(VisionEffectController), nameof(VisionEffectController.SetVisionEffect))] 163 | private static void TurnOffAmplifyPostProcessing(VisionEffectController __instance) 164 | { 165 | __instance.PostProcessScript.enabled = false; 166 | } 167 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrCamera/Patches/UICameraPatches.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BendyVR_5.src; 3 | using HarmonyLib; 4 | using TMG.Core; 5 | using TMG.UI; 6 | using UnityEngine; 7 | using UnityEngine.XR; 8 | 9 | namespace BendyVR_5.VrCamera.Patches; 10 | 11 | [HarmonyPatch] 12 | public class UICameraPatches : BendyVRPatch 13 | { 14 | //Camera.farClipPlane = 5000; 15 | 16 | [HarmonyPostfix] 17 | [HarmonyPatch(typeof(UIManager), nameof(UIManager.Init))] 18 | private static void SetupMenuCamera(UIManager __instance) 19 | { 20 | __instance.Camera.farClipPlane = 5000; 21 | __instance.Camera.nearClipPlane = 0.01f; 22 | 23 | //Lets give the Camera a Parent and a Dampener 24 | UICameraManager.Create(__instance.Camera); 25 | 26 | //Set the camera to not be auto tracked 27 | //XRDevice.DisableAutoXRCameraTracking(__instance.Camera, true); 28 | } 29 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrCamera/UICameraManager.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.Stage; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using UnityEngine.XR; 6 | 7 | namespace BendyVR_5.VrCamera; 8 | 9 | public class UICameraManager : MonoBehaviour 10 | { 11 | private Camera mUICamera; 12 | private Transform mUICameraParentParent; 13 | private Transform mUICameraParent; 14 | private float mUICentre = 0f; 15 | private float mRange = 40f; 16 | private float mLerp = 0f; 17 | private float mLerpSpeed = 0.01f; 18 | private Vector3 mTargetLerp; 19 | 20 | public static void Create(Camera UICamera) 21 | { 22 | var gameObject = GameObject.FindGameObjectWithTag("UIVisualControls"); 23 | var instance = gameObject.AddComponent(); 24 | instance.mUICamera = UICamera; 25 | 26 | //RoomScale Mid Tier Dampening 27 | instance.mUICameraParentParent = new GameObject("UICameraParentParent").transform; 28 | instance.mUICameraParentParent.localPosition = new Vector3(0f, 0f, -900f); 29 | instance.mUICameraParentParent.localRotation = Quaternion.identity; 30 | instance.mUICameraParentParent.transform.SetParent(gameObject.transform); 31 | 32 | instance.mUICameraParent = new GameObject("UICameraParent").transform; 33 | instance.mUICameraParent.transform.SetParent(instance.mUICameraParentParent.transform); 34 | instance.mUICameraParent.localPosition = new Vector3(0f, 0f, 900f); 35 | instance.mUICameraParent.localRotation = Quaternion.identity; 36 | instance.mUICamera.transform.SetParent(instance.mUICameraParent, false); 37 | } 38 | 39 | private void Start() 40 | { 41 | 42 | } 43 | 44 | private void Update() 45 | { 46 | /*if (VrCore.instance.GetVRPlayerController().inLevel) 47 | { 48 | //So lets try and lerp the CameraParent to match the opposite rotation 49 | //Firstly lets get the rotation 50 | Vector3 rotation = mUICamera.transform.localRotation.eulerAngles; 51 | //Vector3 newPosition = mUICamera.transform.localPosition; 52 | if ((mUICameraParentParent.transform.rotation.y + 10 > -rotation.y || 53 | mUICameraParentParent.transform.rotation.y - 10 < -rotation.y) && 54 | mTargetLerp != new Vector3(0f, -rotation.y, 0f)) 55 | { 56 | mTargetLerp = new Vector3(0f, -rotation.y, 0f); 57 | mLerp = 0.00f; 58 | } 59 | if (mLerp <= 1.0f) 60 | { 61 | Quaternion qr = Quaternion.Euler(mTargetLerp); 62 | mUICameraParentParent.transform.rotation = Quaternion.Lerp(mUICameraParentParent.transform.rotation, qr, mLerp); 63 | mLerp += 0.01f; 64 | } 65 | }*/ 66 | 67 | 68 | //Lets just set it instantly to test 69 | //mUICameraParent.transform.RotateAround(mUICamera.transform.localPosition, Vector3.up, -rotation.y); 70 | 71 | //Here's an idea... if we hit rotation of 0 just reset everything 72 | Vector3 rotation = mUICamera.transform.localRotation.eulerAngles; 73 | float offset = rotation.y - mUICentre; 74 | if (offset >= 360f) 75 | { 76 | offset -= 360f; 77 | } 78 | if (offset < 0f) 79 | { 80 | offset += 360f; 81 | } 82 | //Logs.WriteInfo(string.Format("Y: {0} Center: {1} Offset: {2}", rotation.y, mUICentre, offset)); 83 | if (offset > mRange && offset < 180f) 84 | { 85 | mUICentre = rotation.y - mRange; 86 | if (mTargetLerp != new Vector3(0f, mRange - rotation.y, 0f)) 87 | { 88 | mTargetLerp = new Vector3(0f, mRange - rotation.y, 0f); 89 | //mTargetLerp = new Vector3(0f, rotation.y, 0f); 90 | //Quaternion qr = Quaternion.Euler(mTargetLerp); 91 | if (mLerp >= 1f) 92 | mLerp = 0.01f; 93 | } 94 | //mUICameraParentParent.transform.rotation = Quaternion.Lerp(mUICameraParentParent.transform.rotation, qr, mLerp); 95 | 96 | //mUICameraParentParent.transform.localEulerAngles = mTargetLerp; 97 | } 98 | else if (offset < 360f - mRange && offset > 180f) 99 | { 100 | mUICentre = (rotation.y + mRange) - 360f; 101 | if (mTargetLerp != new Vector3(0f, (360f - rotation.y) - mRange, 0f)) 102 | { 103 | mTargetLerp = new Vector3(0f, (360f - rotation.y) - mRange, 0f); 104 | if(mLerp >= 1f) 105 | mLerp = 0.01f; 106 | } 107 | //Quaternion qr = Quaternion.Euler(mTargetLerp); 108 | //mUICameraParentParent.transform.rotation = Quaternion.Lerp(mUICameraParentParent.transform.rotation, qr, mLerp); 109 | //mUICameraParentParent.transform.localEulerAngles = mTargetLerp; 110 | } 111 | 112 | if (mLerp < 1.0f) 113 | { 114 | Quaternion qr = Quaternion.Euler(mTargetLerp); 115 | mUICameraParentParent.transform.rotation = Quaternion.Lerp(mUICameraParentParent.transform.rotation, qr, mLerp * mLerpSpeed); 116 | mLerp += Time.deltaTime; 117 | } 118 | 119 | //mUICameraParentParent.transform.localPosition = new Vector3(-newPosition.x, 0f, 0f); 120 | } 121 | 122 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrCamera/VrCameraManager.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.Stage; 3 | using UnityEngine; 4 | using UnityEngine.XR; 5 | using UnityStandardAssets.ImageEffects; 6 | 7 | namespace BendyVR_5.VrCamera; 8 | 9 | public class VRCameraManager : MonoBehaviour 10 | { 11 | private Camera camera; 12 | private Color cameraBackgroundColor; 13 | //private vgCameraController cameraController; 14 | private int cameraCullingMask; 15 | private int pauseCameraCullingMask; 16 | private Transform playerTransform; 17 | private VrCore stage; 18 | 19 | public static VRCameraManager Create(VrCore stage) 20 | { 21 | var instance = stage.gameObject.AddComponent(); 22 | instance.stage = stage; 23 | return instance; 24 | } 25 | 26 | public void SetUp(Camera newCamera, Transform newPlayerTransform) 27 | { 28 | camera = newCamera; 29 | playerTransform = newPlayerTransform; 30 | //cameraController = FindObjectOfType(); 31 | SetUpCamera(); 32 | DisableCameraComponents(); 33 | // Recenter camera after a while. Just in case it didn't work the first time. 34 | Invoke(nameof(RecenterIncludingVertical), 1); 35 | } 36 | 37 | private void Start() 38 | { 39 | pauseCameraCullingMask = LayerHelper.GetMask( 40 | GameLayer.UI, 41 | GameLayer.MenuBackground, 42 | GameLayer.VrHands); 43 | } 44 | 45 | private void Update() 46 | { 47 | //UpdateCulling(); 48 | } 49 | 50 | private void UpdateCulling() 51 | { 52 | /*if (!vgPauseManager.Instance) return; 53 | 54 | if (cameraCullingMask == 0 && vgPauseManager.Instance.isPaused) 55 | { 56 | cameraCullingMask = camera.cullingMask; 57 | cameraBackgroundColor = camera.backgroundColor; 58 | camera.cullingMask = pauseCameraCullingMask; 59 | camera.clearFlags = CameraClearFlags.Color; 60 | camera.backgroundColor = Color.black; 61 | } 62 | else if (cameraCullingMask != 0 && !vgPauseManager.Instance.isPaused) 63 | { 64 | camera.cullingMask = cameraCullingMask; 65 | cameraCullingMask = 0; 66 | camera.clearFlags = CameraClearFlags.Skybox; 67 | camera.backgroundColor = cameraBackgroundColor; 68 | }*/ 69 | 70 | if (cameraCullingMask == 0) 71 | { 72 | cameraCullingMask = camera.cullingMask; 73 | cameraBackgroundColor = camera.backgroundColor; 74 | camera.cullingMask = pauseCameraCullingMask; 75 | camera.clearFlags = CameraClearFlags.Color; 76 | camera.backgroundColor = Color.black; 77 | } 78 | else if (cameraCullingMask != 0) 79 | { 80 | camera.cullingMask = cameraCullingMask; 81 | cameraCullingMask = 0; 82 | camera.clearFlags = CameraClearFlags.Skybox; 83 | camera.backgroundColor = cameraBackgroundColor; 84 | } 85 | } 86 | 87 | private void RecenterIncludingVertical() 88 | { 89 | RecenterPosition(true); 90 | RecenterRotation(); 91 | } 92 | 93 | private void SetUpCamera() 94 | { 95 | camera.nearClipPlane = 0.03f; 96 | camera.farClipPlane = 3000f; 97 | var cameraTransform = camera.transform; 98 | 99 | if (cameraTransform.parent && cameraTransform.parent.name == "VrCameraParent") return; 100 | 101 | // If the camera starts with an offset position, the tracking will always be incorrect. 102 | // So I disable VR, reset the camera position, and then enable VR again. 103 | XRSettings.enabled = false; 104 | 105 | var cameraParent = new GameObject("VrCameraParent").transform; 106 | cameraParent.SetParent(cameraTransform.parent, false); 107 | cameraTransform.SetParent(cameraParent.transform); 108 | cameraTransform.localPosition = Vector3.zero; 109 | cameraTransform.localRotation = Quaternion.identity; 110 | FakeParenting.Create(cameraParent, stage.transform); 111 | XRSettings.enabled = true; 112 | } 113 | 114 | private void DisableCameraComponents() 115 | { 116 | //DisableCameraComponent(); 117 | //DisableCameraComponent(); 118 | //DisableCameraComponent(); 119 | //DisableCameraComponent(); 120 | //DisableCameraComponent(); 121 | //DisableCameraComponent(); 122 | } 123 | 124 | private void DisableCameraComponent() where TComponent : Behaviour 125 | { 126 | var component = camera.GetComponent(); 127 | if (!component) return; 128 | component.enabled = false; 129 | } 130 | 131 | private Vector3 GetCameraOffset() 132 | { 133 | /*try 134 | { 135 | return camera.transform.position - cameraController.eyeTransform.position; 136 | } 137 | catch 138 | { 139 | return Vector3.zero; 140 | }*/ 141 | return Vector3.zero; 142 | } 143 | 144 | public void RecenterPosition(bool recenterVertically = false) 145 | { 146 | if (!playerTransform || !camera) return; 147 | var cameraOffset = GetCameraOffset(); 148 | if (!recenterVertically) cameraOffset.y = 0; 149 | transform.position -= cameraOffset; 150 | } 151 | 152 | public void RecenterRotation() 153 | { 154 | if (!playerTransform || !camera) return; 155 | var angleOffset = playerTransform.eulerAngles.y - camera.transform.eulerAngles.y; 156 | transform.RotateAround(playerTransform.position, Vector3.up, angleOffset); 157 | transform.eulerAngles = Vector3.up * transform.eulerAngles.y; 158 | } 159 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/ActionInputs/ActionInput.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Settings; 2 | using Valve.VR; 3 | 4 | namespace BendyVR_5.VrInput.ActionInputs; 5 | 6 | public abstract class ActionInput : IActionInput where TAction : ISteamVR_Action_In 7 | { 8 | protected readonly TAction SpecificAction; 9 | 10 | protected ActionInput(TAction action) 11 | { 12 | SpecificAction = action; 13 | } 14 | 15 | private SteamVR_Input_Sources HandSource 16 | { 17 | get 18 | { 19 | var isLeftHanded = VrSettings.LeftHandedMode.Value; 20 | var isSwappedSticks = VrSettings.SwapSticks.Value; 21 | if (SpecificAction.actionSet == SteamVR_Actions.DominantHand) 22 | return isLeftHanded ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand; 23 | if (SpecificAction.actionSet == SteamVR_Actions.NonDominantHand) 24 | return isLeftHanded ? SteamVR_Input_Sources.RightHand : SteamVR_Input_Sources.LeftHand; 25 | if (SpecificAction.actionSet == SteamVR_Actions.RotationHand) 26 | return isSwappedSticks ? SteamVR_Input_Sources.LeftHand : SteamVR_Input_Sources.RightHand; 27 | if (SpecificAction.actionSet == SteamVR_Actions.MovementHand) 28 | return isSwappedSticks ? SteamVR_Input_Sources.RightHand : SteamVR_Input_Sources.LeftHand; 29 | return SteamVR_Input_Sources.Any; 30 | } 31 | } 32 | 33 | public ISteamVR_Action_In Action => SpecificAction; 34 | public float AxisValue => GetAxisValue(HandSource); 35 | public bool ButtonValue => GetButtonValue(HandSource); 36 | public bool ButtonUp => GetButtonUp(HandSource); 37 | public bool ButtonDown => GetButtonDown(HandSource); 38 | 39 | public SteamVR_Input_Sources ActiveSource 40 | { 41 | get 42 | { 43 | if (HandSource != SteamVR_Input_Sources.Any) return HandSource; 44 | 45 | return Action != null && Action.active ? Action.activeDevice : SteamVR_Input_Sources.Any; 46 | } 47 | } 48 | 49 | private float GetAxisValue(SteamVR_Input_Sources source) 50 | { 51 | return Action.active ? GetValue(source) : 0; 52 | } 53 | 54 | private bool GetButtonValue(SteamVR_Input_Sources source) 55 | { 56 | return Action.active && GetValue(source) != 0; 57 | } 58 | 59 | private bool GetButtonUp(SteamVR_Input_Sources source) 60 | { 61 | return Action.active && GetValueUp(source); 62 | } 63 | 64 | private bool GetButtonDown(SteamVR_Input_Sources source) 65 | { 66 | return Action.active && GetValueDown(source); 67 | } 68 | 69 | protected abstract float GetValue(SteamVR_Input_Sources source); 70 | protected abstract bool GetValueUp(SteamVR_Input_Sources source); 71 | protected abstract bool GetValueDown(SteamVR_Input_Sources source); 72 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/ActionInputs/ActionInputDefinitions.cs: -------------------------------------------------------------------------------- 1 | using static Valve.VR.SteamVR_Actions; 2 | 3 | namespace BendyVR_5.VrInput.ActionInputs; 4 | 5 | public static class ActionInputDefinitions 6 | { 7 | //Non-Dominant Hand 8 | public static readonly BooleanActionInput Pause = new(NonDominantHand.Pause); //Default: Y 9 | public static readonly BooleanActionInput Interact = new(NonDominantHand.Interact); //Default: B 10 | 11 | //Dominant Hand 12 | public static readonly BooleanActionInput SeeingTool = new(DominantHand.SeeingTool); //Default: B 13 | public static readonly BooleanActionInput Weapon = new(DominantHand.Weapon); //Default: RightTrigger 14 | 15 | //Movement Hand 16 | public static readonly BooleanActionInput Run = new(MovementHand.Run); //JoystickTrigger 17 | public static readonly Vector2ActionInput MoveX = new(MovementHand.Move); //Joystick 18 | public static readonly Vector2ActionInput MoveY = new(MovementHand.Move, true); //Joystick 19 | 20 | //Rotation Hand 21 | public static readonly BooleanActionInput UiUp = new(RotationHand.UiUp); //JoystickUp 22 | public static readonly BooleanActionInput UiDown = new(RotationHand.UiDown); //JoystickDown 23 | public static readonly BooleanActionInput Next = new(RotationHand.Next); //JoystickRight 24 | public static readonly BooleanActionInput Previous = new(RotationHand.Previous); //JoystickLeft 25 | public static readonly Vector2ActionInput RotateX = new(RotationHand.Rotate); //JoystickX 26 | public static readonly BooleanActionInput SnapTurnLeft = new(RotationHand.SnapTurnLeft); //JoystickLeft 27 | public static readonly BooleanActionInput SnapTurnRight = new(RotationHand.SnapTurnRight); //JoystickRight 28 | public static readonly BooleanActionInput Jump = new(RotationHand.Jump); //Default: A 29 | public static readonly BooleanActionInput Cancel = new(RotationHand.Cancel); //Default: B 30 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/ActionInputs/BooleanActionInput.cs: -------------------------------------------------------------------------------- 1 | using Valve.VR; 2 | 3 | namespace BendyVR_5.VrInput.ActionInputs; 4 | 5 | public class BooleanActionInput : ActionInput 6 | { 7 | public BooleanActionInput(SteamVR_Action_Boolean action) : 8 | base(action) 9 | { 10 | } 11 | 12 | protected override float GetValue(SteamVR_Input_Sources source) 13 | { 14 | return SpecificAction.GetState(source) ? 1 : 0; 15 | } 16 | 17 | protected override bool GetValueUp(SteamVR_Input_Sources source) 18 | { 19 | return SpecificAction.GetStateUp(source); 20 | } 21 | 22 | protected override bool GetValueDown(SteamVR_Input_Sources source) 23 | { 24 | return SpecificAction.GetStateDown(source); 25 | } 26 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/ActionInputs/EmptyActionInput.cs: -------------------------------------------------------------------------------- 1 | using Valve.VR; 2 | 3 | namespace BendyVR_5.VrInput.ActionInputs; 4 | 5 | public class EmptyActionInput : ActionInput 6 | { 7 | public EmptyActionInput(string texturePath = null) : base(null) 8 | { 9 | TexturePath = texturePath; 10 | } 11 | 12 | public string TexturePath { get; } 13 | 14 | protected override float GetValue(SteamVR_Input_Sources source) 15 | { 16 | return 0; 17 | } 18 | 19 | protected override bool GetValueUp(SteamVR_Input_Sources source) 20 | { 21 | return false; 22 | } 23 | 24 | protected override bool GetValueDown(SteamVR_Input_Sources source) 25 | { 26 | return false; 27 | } 28 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/ActionInputs/IActionInput.cs: -------------------------------------------------------------------------------- 1 | using Valve.VR; 2 | 3 | namespace BendyVR_5.VrInput.ActionInputs; 4 | 5 | public interface IActionInput 6 | { 7 | ISteamVR_Action_In Action { get; } 8 | float AxisValue { get; } 9 | bool ButtonValue { get; } 10 | bool ButtonUp { get; } 11 | bool ButtonDown { get; } 12 | SteamVR_Input_Sources ActiveSource { get; } 13 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/ActionInputs/Vector2ActionInput.cs: -------------------------------------------------------------------------------- 1 | using Valve.VR; 2 | 3 | namespace BendyVR_5.VrInput.ActionInputs; 4 | 5 | public class Vector2ActionInput : ActionInput 6 | { 7 | private readonly bool yOnly; 8 | 9 | public Vector2ActionInput(SteamVR_Action_Vector2 action, 10 | bool yOnly = false, 11 | string textureModifier = null) : base(action) 12 | { 13 | this.yOnly = yOnly; 14 | TextureModifier = textureModifier; 15 | } 16 | 17 | public string TextureModifier { get; } 18 | 19 | protected override float GetValue(SteamVR_Input_Sources source) 20 | { 21 | var axis = SpecificAction.GetAxis(source); 22 | return yOnly ? axis.y : axis.x; 23 | } 24 | 25 | protected override bool GetValueUp(SteamVR_Input_Sources source) 26 | { 27 | return false; 28 | } 29 | 30 | protected override bool GetValueDown(SteamVR_Input_Sources source) 31 | { 32 | return false; 33 | } 34 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/BindingsManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using BepInEx.Configuration; 3 | //using BendyVR_5.Settings; 4 | using BendyVR_5.Stage; 5 | using BendyVR_5.VrInput.ActionInputs; 6 | using UnityEngine; 7 | using Valve.VR; 8 | using InControl; 9 | 10 | namespace BendyVR_5.VrInput; 11 | 12 | public class BindingsManager : MonoBehaviour 13 | { 14 | public readonly Dictionary ActionMap = new() 15 | { 16 | {VirtualKey.Run, ActionInputDefinitions.Run}, 17 | {VirtualKey.Use, ActionInputDefinitions.Interact}, 18 | {VirtualKey.Confirm, ActionInputDefinitions.Interact}, 19 | {VirtualKey.Jump, ActionInputDefinitions.Jump}, 20 | {VirtualKey.Cancel, ActionInputDefinitions.Cancel}, 21 | {VirtualKey.DialogUp, ActionInputDefinitions.UiUp}, 22 | {VirtualKey.DialogDown, ActionInputDefinitions.UiDown}, 23 | {VirtualKey.Pause, ActionInputDefinitions.Cancel}, 24 | {VirtualKey.NextMenu, ActionInputDefinitions.Next}, 25 | {VirtualKey.PreviousMenu, ActionInputDefinitions.Previous}, 26 | {VirtualKey.MoveXAxis, ActionInputDefinitions.MoveX}, 27 | {VirtualKey.LookXAxisStick, ActionInputDefinitions.RotateX}, 28 | {VirtualKey.MoveYAxis, ActionInputDefinitions.MoveY}, 29 | {VirtualKey.MoveForwardKeyboard, ActionInputDefinitions.UiUp}, 30 | {VirtualKey.MoveBackwardKeyboard, ActionInputDefinitions.UiDown}, 31 | {VirtualKey.StrafeRightKeyboard, ActionInputDefinitions.Next}, 32 | {VirtualKey.StrafeLeftKeyboard, ActionInputDefinitions.Previous}, 33 | // Unused for actually controlling stuff, but used for the input prompts. 34 | {VirtualKey.ScrollUpDown, ActionInputDefinitions.UiUp}, 35 | {VirtualKey.Melee, ActionInputDefinitions.Weapon} 36 | }; 37 | 38 | public static BindingsManager Create(VrCore stage) 39 | { 40 | var instance = stage.gameObject.AddComponent(); 41 | return instance; 42 | } 43 | 44 | private void Awake() 45 | { 46 | ActivateSteamVrActionSets(); 47 | } 48 | 49 | private void OnEnable() 50 | { 51 | SteamVR_Events.System(EVREventType.VREvent_Input_BindingsUpdated).Listen(HandleVrBindingsUpdated); 52 | //VrSettings.Config.SettingChanged += HandleSettingChanged; 53 | } 54 | 55 | private void OnDisable() 56 | { 57 | SteamVR_Events.System(EVREventType.VREvent_Input_BindingsUpdated).Remove(HandleVrBindingsUpdated); 58 | //VrSettings.Config.SettingChanged -= HandleSettingChanged; 59 | } 60 | 61 | private void ActivateSteamVrActionSets() 62 | { 63 | foreach (var actionSet in SteamVR_Input.actionSets) actionSet.Activate(); 64 | } 65 | 66 | private static void HandleSettingChanged(object sender, SettingChangedEventArgs e) 67 | { 68 | UpdatePrompts(); 69 | } 70 | 71 | private static void HandleVrBindingsUpdated(VREvent_t arg0) 72 | { 73 | UpdatePrompts(); 74 | } 75 | 76 | private static void UpdatePrompts() 77 | { 78 | if (!InputManager.IsSetup) return; 79 | 80 | // This resets the input prompts. The layout choice argument isn't actually used. 81 | //InputManager.Instance.SetControllerLayout(vgControllerLayoutChoice.KeyboardMouse); 82 | } 83 | 84 | public float GetValue(string virtualKey) 85 | { 86 | ActionMap.TryGetValue(virtualKey, out var actionInput); 87 | if (actionInput == null) return 0; 88 | 89 | return actionInput.AxisValue; 90 | } 91 | 92 | public bool GetUp(string virtualKey) 93 | { 94 | ActionMap.TryGetValue(virtualKey, out var actionInput); 95 | if (actionInput == null) return false; 96 | 97 | return actionInput.ButtonUp; 98 | } 99 | 100 | public bool GetDown(string virtualKey) 101 | { 102 | ActionMap.TryGetValue(virtualKey, out var actionInput); 103 | if (actionInput == null) return false; 104 | 105 | return actionInput.ButtonDown; 106 | } 107 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/CommandName.cs: -------------------------------------------------------------------------------- 1 | namespace BendyVR_5.VrInput; 2 | 3 | public struct CommandName 4 | { 5 | public const string None = ""; 6 | public const string AltUse = "AltUse"; 7 | public const string BackwardKeyDown = "BackwardKeyDown"; 8 | public const string BackwardKeyUp = "BackwardKeyUp"; 9 | public const string Camera = "Camera"; 10 | public const string CompassZoomIn = "CompassZoomIn"; 11 | public const string CompassZoomOut = "CompassZoomOut"; 12 | public const string DemoTeleport = "DemoTeleport"; 13 | public const string DialogSelectionDown = "DialogSelectionDown"; 14 | public const string DialogSelectionDownOrUse = "DialogSelectionDownOrUse"; 15 | public const string DialogSelectionScroll = "DialogSelectionScroll"; 16 | public const string DialogSelectionUp = "DialogSelectionUp"; 17 | public const string DisplayInventory = "DisplayInventory"; 18 | public const string EquipCompass = "EquipCompass"; 19 | public const string EquipMap = "EquipMap"; 20 | public const string Flashlight = "Flashlight"; 21 | public const string ForwardKeyDown = "ForwardKeyDown"; 22 | public const string ForwardKeyUp = "ForwardKeyUp"; 23 | public const string HideInventory = "HideInventory"; 24 | public const string HorizontalMouse = "Horizontal_Mouse"; 25 | public const string HorizontalStick = "Horizontal_Stick"; 26 | public const string InventoryRotateHorizontal = "InventoryRotateHorizontal"; 27 | public const string InventoryRotateHorizontalStick = "InventoryRotateHorizontal_Stick"; 28 | public const string InventoryRotateVertical = "InventoryRotateVertical"; 29 | public const string InventoryRotateVerticalStick = "InventoryRotateVertical_Stick"; 30 | public const string InventoryZoomIn = "InventoryZoomIn"; 31 | public const string InventoryZoomInTrigger = "InventoryZoomInTrigger"; 32 | public const string Key0 = "Key0"; 33 | public const string Key1 = "Key1"; 34 | public const string Key2 = "Key2"; 35 | public const string Key3 = "Key3"; 36 | public const string Key4 = "Key4"; 37 | public const string Key5 = "Key5"; 38 | public const string Key6 = "Key6"; 39 | public const string Key7 = "Key7"; 40 | public const string Key8 = "Key8"; 41 | public const string Key9 = "Key9"; 42 | public const string Lean = "Lean"; 43 | public const string LeanDown = "LeanDown"; 44 | public const string LeanHorizontal = "LeanHorizontal"; 45 | public const string LeanLeft = "LeanLeft"; 46 | public const string LeanRight = "LeanRight"; 47 | public const string LeanUp = "LeanUp"; 48 | public const string LeanVertical = "LeanVertical"; 49 | public const string LockCancel = "LockCancel"; 50 | public const string LockNumberDown = "LockNumberDown"; 51 | public const string LockNumberUp = "LockNumberUp"; 52 | public const string LockTry = "LockTry"; 53 | public const string LockTumblerLeft = "LockTumblerLeft"; 54 | public const string LockTumblerRight = "LockTumblerRight"; 55 | public const string LocomotionAction = "LocomotionAction"; 56 | public const string LocomotionActionOrToggleJog = "LocomotionActionOrToggleJog"; 57 | public const string LocomotionActionRelease = "LocomotionActionRelease"; 58 | public const string LookHorizontalMouse = "LookHorizontal_Mouse"; 59 | public const string LookHorizontalStick = "LookHorizontal_Stick"; 60 | public const string LookVerticalMouse = "LookVertical_Mouse"; 61 | public const string LookVerticalStick = "LookVertical_Stick"; 62 | public const string MapZoomIn = "MapZoomIn"; 63 | public const string MapZoomOut = "MapZoomOut"; 64 | public const string MoveForward = "MoveForward"; 65 | public const string MoveStrafe = "MoveStrafe"; 66 | public const string NextMenu = "NextMenu"; 67 | public const string Pause = "Pause"; 68 | public const string PressDemoKey1 = "PressDemoKey1"; 69 | public const string PressDemoKey2 = "PressDemoKey2"; 70 | public const string PressDemoKey3 = "PressDemoKey3"; 71 | public const string PressDemoKey4 = "PressDemoKey4"; 72 | public const string PreviousMenu = "PreviousMenu"; 73 | public const string PutDownItem = "PutDownItem"; 74 | public const string QuickLoad = "QuickLoad"; 75 | public const string QuickSave = "QuickSave"; 76 | public const string RadioDown = "RadioDown"; 77 | public const string RadioUp = "RadioUp"; 78 | public const string ReadMode = "ReadMode"; 79 | public const string Scroll = "Scroll"; 80 | public const string StartInventoryRotation = "StartInventoryRotation"; 81 | public const string StopInventoryRotation = "StopInventoryRotation"; 82 | public const string StopLean = "StopLean"; 83 | public const string StopStowHeldObject = "StopStowHeldObject"; 84 | public const string StowHeldObject = "StowHeldObject"; 85 | public const string StrafeLeftKeyDown = "StrafeLeftKeyDown"; 86 | public const string StrafeLeftKeyUp = "StrafeLeftKeyUp"; 87 | public const string StrafeRightKeyDown = "StrafeRightKeyDown"; 88 | public const string StrafeRightKeyUp = "StrafeRightKeyUp"; 89 | public const string Titlecard = "Titlecard"; 90 | public const string ToggleCompass = "ToggleCompass"; 91 | public const string ToggleJog = "ToggleJog"; 92 | public const string ToggleMap = "ToggleMap"; 93 | public const string ToggleReading = "ToggleReading"; 94 | public const string TossItem = "TossItem"; 95 | public const string UICancel = "UICancel"; 96 | public const string UISubmit = "UISubmit"; 97 | public const string UIClick = "UIClick"; 98 | public const string UILeft = "UILeft"; 99 | public const string UIRight = "UIRight"; 100 | public const string UIUp = "UIUp"; 101 | public const string UIDown = "UIDown"; 102 | public const string UIVertical = "UIVertical"; 103 | public const string UIHorizontal = "UIHorizontal"; 104 | public const string UnCrouch = "UnCrouch"; 105 | public const string UnequipCompass = "UnequipCompass"; 106 | public const string UnequipMap = "UnequipMap"; 107 | public const string UnPause = "UnPause"; 108 | public const string Use = "Use"; 109 | public const string UseCamera = "UseCamera"; 110 | public const string VerticalMouse = "Vertical_Mouse"; 111 | public const string VerticalStick = "Vertical_Stick"; 112 | public const string WindUpToss = "WindUpToss"; 113 | public const string ZoomIn = "ZoomIn"; 114 | public const string ZoomInOnHeldObject = "ZoomInOnHeldObject"; 115 | public const string ZoomOut = "ZoomOut"; 116 | public const string ZoomOutOnHeldObject = "ZoomOutOnHeldObject"; 117 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/Patches/BindingsPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using BendyVR_5.src; 4 | using BepInEx; 5 | using HarmonyLib; 6 | //using BendyVR_5.Settings; 7 | using UnityEngine; 8 | using Valve.VR; 9 | 10 | namespace BendyVR_5.VrInput.Patches; 11 | 12 | [HarmonyPatch] 13 | public class BindingsPatches : BendyVRPatch 14 | { 15 | private const float outerDeadzone = 0.5f; 16 | private const float innerDeadzone = 0.1f; 17 | 18 | private static readonly HashSet ignoredVirtualKeys = new() 19 | { 20 | VirtualKey.ScrollUpDown, 21 | VirtualKey.Melee 22 | }; 23 | 24 | private static readonly Dictionary> replacementCommandMap = 25 | new() 26 | { 27 | { 28 | VirtualKey.DialogDown, 29 | new Dictionary 30 | { 31 | // Fixes UIDown triggering interact. 32 | {CommandName.DialogSelectionDownOrUse, CommandName.DialogSelectionDown}, 33 | 34 | // Fixes UIDown triggering lock tumbler right.. 35 | {CommandName.LockTumblerRight, CommandName.None} 36 | } 37 | }, 38 | // Keyboard move keys are needed to interact with locks and UI stuff, 39 | // but need to prevent them from triggering player movement. 40 | { 41 | VirtualKey.MoveBackwardKeyboard, 42 | new Dictionary 43 | { 44 | {CommandName.BackwardKeyDown, CommandName.None}, 45 | {CommandName.BackwardKeyUp, CommandName.None} 46 | } 47 | }, 48 | { 49 | VirtualKey.MoveForwardKeyboard, 50 | new Dictionary 51 | { 52 | {CommandName.ForwardKeyDown, CommandName.None}, 53 | {CommandName.ForwardKeyUp, CommandName.None} 54 | } 55 | }, 56 | { 57 | VirtualKey.StrafeLeftKeyboard, 58 | new Dictionary 59 | { 60 | {CommandName.StrafeLeftKeyDown, CommandName.None}, 61 | {CommandName.StrafeLeftKeyUp, CommandName.None} 62 | } 63 | }, 64 | { 65 | VirtualKey.StrafeRightKeyboard, 66 | new Dictionary 67 | { 68 | {CommandName.StrafeRightKeyDown, CommandName.None}, 69 | {CommandName.StrafeRightKeyUp, CommandName.None} 70 | } 71 | } 72 | }; 73 | 74 | 75 | 76 | [HarmonyPrefix] 77 | [HarmonyPatch(typeof(SteamVR_Input), nameof(SteamVR_Input.GetActionsFileFolder))] 78 | private static bool GetActionsFileFromMod(ref string __result) 79 | { 80 | __result = Path.Combine(Paths.PluginPath, Path.Combine("BendyVRAssets", "Bindings")); 81 | //__result = $"{Directory.GetCurrentDirectory()}/BepInEx/plugins/baggyg-bendyvr/BendyVRAssets/Bindings"; 82 | return false; 83 | } 84 | 85 | private static float ProcessAxisValue(float value) 86 | { 87 | var valueSign = Mathf.Sign(value); 88 | var absoluteValue = Mathf.Abs(value); 89 | return valueSign * Mathf.InverseLerp(innerDeadzone, 1f - outerDeadzone, absoluteValue); 90 | } 91 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/Patches/InputManagerPatches.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.Helpers; 2 | using BendyVR_5.src; 3 | using BendyVR_5.VrInput.ActionInputs; 4 | using HarmonyLib; 5 | using InControl; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using UnityEngine; 11 | using Valve.VR; 12 | 13 | namespace BendyVR_5.VrInput.Patches; 14 | 15 | [HarmonyPatch] 16 | public class InputManagerPatches : BendyVRPatch 17 | { 18 | /*[HarmonyPrefix] 19 | [HarmonyPatch(typeof(InputManager), nameof(InputManager.SetupInternal))] 20 | internal static bool CustomSetupInternal(ref bool __result) 21 | { 22 | if (InputManager.IsSetup) 23 | { 24 | return false; 25 | } 26 | InputManager.Platform = Utility.GetWindowsVersion().ToUpper(); 27 | InputManager.enabled = true; 28 | InputManager.initialTime = 0f; 29 | InputManager.currentTime = 0f; 30 | InputManager.lastUpdateTime = 0f; 31 | InputManager.currentTick = 0uL; 32 | InputManager.applicationIsFocused = true; 33 | InputManager.deviceManagers.Clear(); 34 | InputManager.deviceManagerTable.Clear(); 35 | InputManager.devices.Clear(); 36 | InputManager.Devices = InputManager.devices.AsReadOnly(); 37 | InputManager.activeDevice = InputDevice.Null; 38 | InputManager.activeDevices.Clear(); 39 | InputManager.ActiveDevices = InputManager.activeDevices.AsReadOnly(); 40 | InputManager.playerActionSets.Clear(); 41 | InputManager.IsSetup = true; 42 | bool flag = true; 43 | if (InputManager.OnSetup != null) 44 | { 45 | InputManager.OnSetup(); 46 | InputManager.OnSetup = null; 47 | } 48 | if (flag) 49 | { 50 | AddDeviceManager(); 51 | } 52 | 53 | __result = true; 54 | return __result; 55 | }*/ 56 | 57 | //In VR we need GameManager->HasController to report true, but this is an inline function so can't override it. 58 | //Therefore we will add a dummy device 59 | [HarmonyPrefix] 60 | [HarmonyPatch(typeof(InputManager), nameof(InputManager.UpdateDevices))] 61 | private static bool AddDummyDevice() 62 | { 63 | if(InputManager.Devices.Count == 0) 64 | { 65 | InputDevice inputDevice = new InputDevice("VRDummy", true); 66 | InputManager.devices.Add(inputDevice); 67 | } 68 | return false; 69 | } 70 | 71 | 72 | 73 | 74 | [HarmonyPrefix] 75 | [HarmonyPatch(typeof(InputUtil), nameof(InputUtil.GetInputY),new Type[] { typeof(float), typeof(bool) },new ArgumentType[] { ArgumentType.Out, ArgumentType.Out})] 76 | private static bool ReplaceInputY(ref bool __result, out float axis, out bool hasMouse) 77 | { 78 | float valueUp = ActionInputDefinitions.UiUp.AxisValue; 79 | float valueDown = ActionInputDefinitions.UiDown.AxisValue; 80 | float stickValue = ActionInputDefinitions.MoveY.AxisValue; 81 | /*if (ActionInputDefinitions.MoveY.AxisValue != 0f) 82 | Logs.WriteInfo("MoveY: " + ActionInputDefinitions.MoveY.ActiveSource + ActionInputDefinitions.MoveY.AxisValue.ToString()); 83 | if (ActionInputDefinitions.MoveX.AxisValue != 0f) 84 | Logs.WriteInfo("MoveX: " + ActionInputDefinitions.MoveX.ActiveSource + ActionInputDefinitions.MoveX.AxisValue.ToString()); 85 | if (ActionInputDefinitions.UiUp.AxisValue != 0) 86 | Logs.WriteInfo("UiUp: " + ActionInputDefinitions.UiUp.ActiveSource + ActionInputDefinitions.UiUp.AxisValue.ToString()); 87 | if (ActionInputDefinitions.UiDown.AxisValue != 0) 88 | Logs.WriteInfo("UiDown: " + ActionInputDefinitions.UiDown.ActiveSource + ActionInputDefinitions.UiDown.AxisValue.ToString()); 89 | if (ActionInputDefinitions.Jump.ButtonDown) 90 | Logs.WriteInfo("Jump:" + ActionInputDefinitions.Jump.ActiveSource + ActionInputDefinitions.Jump.ButtonDown.ToString()); 91 | if (ActionInputDefinitions.Weapon.ButtonDown) 92 | Logs.WriteInfo("Weapon:" + ActionInputDefinitions.Weapon.ActiveSource + ActionInputDefinitions.Weapon.ButtonDown.ToString()); 93 | if (ActionInputDefinitions.Interact.ButtonDown) 94 | Logs.WriteInfo("Interact:" + ActionInputDefinitions.Interact.ActiveSource + ActionInputDefinitions.Interact.ButtonDown.ToString());*/ 95 | 96 | hasMouse = false; 97 | axis = 0f; 98 | __result = false; 99 | if (valueUp != 0f) 100 | { 101 | Cursor.lockState = CursorLockMode.Locked; 102 | Cursor.visible = false; 103 | axis = valueUp; 104 | __result = true; 105 | //Logs.WriteInfo("Axis UP: " + axis); 106 | } 107 | else if (valueDown != 0f) 108 | { 109 | Cursor.lockState = CursorLockMode.Locked; 110 | Cursor.visible = false; 111 | axis = -valueDown; 112 | __result = true; 113 | //Logs.WriteInfo("Axis DOWN: " + axis); 114 | } 115 | else if(stickValue != 0f) 116 | { 117 | axis = stickValue; 118 | __result = true; 119 | //Logs.WriteInfo("Stick Movement: " + axis); 120 | } 121 | return false; 122 | } 123 | 124 | [HarmonyPrefix] 125 | [HarmonyPatch(typeof(InputUtil), nameof(InputUtil.GetInputX), new Type[] { typeof(float), typeof(bool) }, new ArgumentType[] { ArgumentType.Out, ArgumentType.Out })] 126 | private static bool ReplaceInputX(ref bool __result, out float axis, out bool hasMouse) 127 | { 128 | float valueLeft = ActionInputDefinitions.Previous.AxisValue; 129 | float valueRight = ActionInputDefinitions.Next.AxisValue; 130 | float stickValue = ActionInputDefinitions.MoveX.AxisValue; 131 | /*if (ActionInputDefinitions.MoveY.AxisValue != 0f) 132 | Logs.WriteInfo("MoveY: " + ActionInputDefinitions.MoveY.ActiveSource + ActionInputDefinitions.MoveY.AxisValue.ToString()); 133 | if (ActionInputDefinitions.MoveX.AxisValue != 0f) 134 | Logs.WriteInfo("MoveX: " + ActionInputDefinitions.MoveX.ActiveSource + ActionInputDefinitions.MoveX.AxisValue.ToString()); 135 | if (ActionInputDefinitions.UiUp.AxisValue != 0) 136 | Logs.WriteInfo("UiUp: " + ActionInputDefinitions.UiUp.ActiveSource + ActionInputDefinitions.UiUp.AxisValue.ToString()); 137 | if (ActionInputDefinitions.UiDown.AxisValue != 0) 138 | Logs.WriteInfo("UiDown: " + ActionInputDefinitions.UiDown.ActiveSource + ActionInputDefinitions.UiDown.AxisValue.ToString()); 139 | if (ActionInputDefinitions.Jump.ButtonDown) 140 | Logs.WriteInfo("Jump:" + ActionInputDefinitions.Jump.ActiveSource + ActionInputDefinitions.Jump.ButtonDown.ToString()); 141 | if (ActionInputDefinitions.Weapon.ButtonDown) 142 | Logs.WriteInfo("Weapon:" + ActionInputDefinitions.Weapon.ActiveSource + ActionInputDefinitions.Weapon.ButtonDown.ToString()); 143 | if (ActionInputDefinitions.Interact.ButtonDown) 144 | Logs.WriteInfo("Interact:" + ActionInputDefinitions.Interact.ActiveSource + ActionInputDefinitions.Interact.ButtonDown.ToString());*/ 145 | 146 | hasMouse = false; 147 | axis = 0f; 148 | __result = false; 149 | if (valueRight != 0f) 150 | { 151 | Cursor.lockState = CursorLockMode.Locked; 152 | Cursor.visible = false; 153 | axis = valueRight; 154 | __result = true; 155 | //Logs.WriteInfo("Axis UP: " + axis); 156 | } 157 | else if (valueLeft != 0f) 158 | { 159 | Cursor.lockState = CursorLockMode.Locked; 160 | Cursor.visible = false; 161 | axis = -valueLeft; 162 | __result = true; 163 | //Logs.WriteInfo("Axis DOWN: " + axis); 164 | } 165 | else if (stickValue != 0f) 166 | { 167 | axis = stickValue; 168 | __result = true; 169 | //Logs.WriteInfo("Stick Movement: " + axis); 170 | } 171 | return false; 172 | } 173 | } 174 | 175 | -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/Patches/InputPromptsPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using BendyVR_5.Helpers; 3 | using BendyVR_5.src; 4 | using BendyVR_5.VrInput.ActionInputs; 5 | using HarmonyLib; 6 | using UnityEngine; 7 | using Valve.VR; 8 | 9 | namespace BendyVR_5.VrInput.Patches; 10 | 11 | [HarmonyPatch] 12 | public class InputPromptsPatches : BendyVRPatch 13 | { 14 | private static readonly TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; 15 | 16 | [HarmonyPostfix] 17 | [HarmonyPatch(typeof(TutorialPopupController), nameof(TutorialPopupController.InitController))] 18 | private static void ReplacePromptIconsWithVrButtonText(TutorialPopupController __instance) 19 | { 20 | Logs.WriteInfo("Repositioning Tutorial"); 21 | __instance.transform.localScale = new Vector3(1.2f, 1.2f, 1.2f); 22 | __instance.transform.localPosition = new Vector3(0f, 1000f, 0f); 23 | __instance.m_ButtonImage.SetActive(value: false); 24 | __instance.m_KeyboardImage.SetActive(value: true); 25 | __instance.m_MouseImageLeft.SetActive(value: false); 26 | __instance.m_MouseImageRight.SetActive(value: false); 27 | __instance.m_MouseImageMiddle.SetActive(value: false); 28 | IActionInput inputAction = ActionInputs.ActionInputDefinitions.Jump; 29 | if (__instance.m_DataVO.ActionRaw == "Tutorial/TUTORIAL_JUMP") 30 | { 31 | inputAction = ActionInputs.ActionInputDefinitions.Jump; 32 | } 33 | else if (__instance.m_DataVO.ActionRaw == "Tutorial/TUTORIAL_RUN") 34 | { 35 | inputAction = ActionInputs.ActionInputDefinitions.Run; 36 | } 37 | else if (__instance.m_DataVO.ActionRaw == "Tutorial/TUTORIAL_SEEING_TOOL") 38 | { 39 | inputAction = ActionInputs.ActionInputDefinitions.SeeingTool; 40 | } 41 | var source = inputAction.ActiveSource; 42 | var hand = ""; 43 | if (source == SteamVR_Input_Sources.RightHand) hand = "right "; 44 | if (source == SteamVR_Input_Sources.LeftHand) hand = "left "; 45 | 46 | var name = inputAction.Action.GetRenderModelComponentName(inputAction.ActiveSource); 47 | name = name.Replace("button_", ""); 48 | name = name.Replace("thumb", ""); 49 | __instance.m_KeyboardLbl.text = textInfo.ToTitleCase($"{hand}{name}"); 50 | } 51 | 52 | /*[HarmonyPrefix] 53 | [HarmonyPatch(typeof(vgButtonIconMap), nameof(vgButtonIconMap.GetIconName))] 54 | private static bool ReplacePromptIconsWithVrButtonText(ref string __result, string id) 55 | { 56 | var inputAction = StageInstance.GetInputAction(id); 57 | if (inputAction?.Action == null || !inputAction.Action.active) 58 | { 59 | __result = "n/a"; 60 | return false; 61 | } 62 | 63 | var source = inputAction.ActiveSource; 64 | var hand = ""; 65 | if (source == SteamVR_Input_Sources.RightHand) hand = "right "; 66 | if (source == SteamVR_Input_Sources.LeftHand) hand = "left "; 67 | 68 | var name = inputAction.Action.GetRenderModelComponentName(inputAction.ActiveSource); 69 | name = name.Replace("button_", ""); 70 | name = name.Replace("thumb", ""); 71 | __result = textInfo.ToTitleCase($"{hand}{name}"); 72 | 73 | return false; 74 | }*/ 75 | 76 | /*[HarmonyPrefix] 77 | [HarmonyPatch(typeof(vgButtonIconMap), nameof(vgButtonIconMap.HasIcon))] 78 | private static bool CheckHasIconFromVrInputs(ref bool __result, string id) 79 | { 80 | __result = true; 81 | return false; 82 | }*/ 83 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/Patches/MousePatches.cs: -------------------------------------------------------------------------------- 1 | using BendyVR_5.src; 2 | using HarmonyLib; 3 | using UnityEngine; 4 | using UnityEngine.EventSystems; 5 | 6 | namespace BendyVR_5.VrInput.Patches; 7 | 8 | [HarmonyPatch] 9 | public class MousePatches : BendyVRPatch 10 | { 11 | [HarmonyPostfix] 12 | [HarmonyPatch(typeof(TitleScreenController), nameof(TitleScreenController.CheckInitialInput))] 13 | private static void HideCursor() 14 | { 15 | Cursor.lockState = CursorLockMode.Locked; 16 | Cursor.visible = false; 17 | } 18 | 19 | [HarmonyPrefix] 20 | [HarmonyPatch(typeof(Input), nameof(Input.GetAxis))] 21 | private static bool RemoveMouseInput(ref float __result, string axisName) 22 | { 23 | if (axisName.ToLower().Equals("mouse x") || axisName.ToLower().Equals("mouse y")) 24 | { 25 | __result = 0f; 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | 32 | /*[HarmonyPrefix] 33 | [HarmonyPatch(typeof(vgCursorManager), nameof(vgCursorManager.Awake))] 34 | private static bool DestroyCursorManager(vgCursorManager __instance) 35 | { 36 | Object.Destroy(__instance); 37 | return false; 38 | }*/ 39 | 40 | 41 | /*[HarmonyPrefix] 42 | [HarmonyPatch(typeof(vgUIInputModule), nameof(vgUIInputModule.ProcessMouseEvent))] 43 | [HarmonyPatch(typeof(vgUIInputModule), nameof(vgUIInputModule.GetDefaultSelectedGameObject))] 44 | private static bool DisableMouse(vgUIInputModule __instance) 45 | { 46 | return false; 47 | }*/ 48 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/Patches/PlayerInputPatches.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using BepInEx.Configuration; 3 | //using BendyVR_5.Settings; 4 | using BendyVR_5.Stage; 5 | using BendyVR_5.VrInput.ActionInputs; 6 | using UnityEngine; 7 | using Valve.VR; 8 | using InControl; 9 | using TMG.Controls; 10 | using HarmonyLib; 11 | using BendyVR_5.src; 12 | 13 | namespace BendyVR_5.VrInput.Patches; 14 | 15 | [HarmonyPatch] 16 | public class PlayerInputPatches : BendyVRPatch 17 | { 18 | [HarmonyPrefix] 19 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Any))] 20 | private static bool Any(ref bool __result) 21 | { 22 | __result = ActionInputDefinitions.Weapon.ButtonDown || 23 | ActionInputDefinitions.SeeingTool.ButtonDown || 24 | ActionInputDefinitions.Run.ButtonDown || 25 | ActionInputDefinitions.Jump.ButtonDown || 26 | ActionInputDefinitions.Pause.ButtonDown || 27 | ActionInputDefinitions.Cancel.ButtonDown || 28 | ActionInputDefinitions.Interact.ButtonDown; 29 | 30 | return false; 31 | } 32 | 33 | [HarmonyPrefix] 34 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Attack))] 35 | private static bool PlayerAttack(ref bool __result) 36 | { 37 | __result = ActionInputDefinitions.Weapon.ButtonDown; 38 | return false; 39 | } 40 | 41 | [HarmonyPrefix] 42 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.SeeingTool))] 43 | private static bool PlayerSeeingTool(ref bool __result) 44 | { 45 | __result = ActionInputDefinitions.SeeingTool.ButtonDown; 46 | return false; 47 | } 48 | 49 | [HarmonyPrefix] 50 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.AttackHold))] 51 | private static bool PlayerAttackHold(ref bool __result) 52 | { 53 | __result = ActionInputDefinitions.Weapon.ButtonValue; 54 | return false; 55 | } 56 | 57 | [HarmonyPrefix] 58 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Run))] 59 | private static bool PlayerRun(ref bool __result) 60 | { 61 | __result = ActionInputDefinitions.Run.ButtonValue; 62 | return false; 63 | } 64 | [HarmonyPrefix] 65 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Jump))] 66 | private static bool PlayerJump(ref bool __result) 67 | { 68 | __result = ActionInputDefinitions.Jump.ButtonDown; 69 | return false; 70 | } 71 | 72 | [HarmonyPrefix] 73 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.Pause))] 74 | private static bool PlayerPause(ref bool __result) 75 | { 76 | __result = ActionInputDefinitions.Pause.ButtonDown; 77 | return false; 78 | } 79 | 80 | [HarmonyPrefix] 81 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.MoveX))] 82 | private static bool PlayerMoveX(ref float __result) 83 | { 84 | __result = ActionInputDefinitions.MoveX.AxisValue; 85 | return false; 86 | } 87 | 88 | [HarmonyPrefix] 89 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.MoveY))] 90 | private static bool PlayerMoveY(ref float __result) 91 | { 92 | __result = ActionInputDefinitions.MoveY.AxisValue; 93 | return false; 94 | } 95 | 96 | //Not sure what to do about LookX / LookY at the moment 97 | [HarmonyPrefix] 98 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.LookX))] 99 | private static bool LookX(ref float __result, float TSpeed = 0f) 100 | { 101 | //return BasePlayerInput.GetInputFloat(GamepadInput.GetAxis(InputControlType.RightStickX) * (1.25f + TSpeed), Input.GetAxis("Mouse X")); 102 | __result = ActionInputDefinitions.RotateX.AxisValue * (1.25f + TSpeed); 103 | return false; 104 | } 105 | 106 | [HarmonyPrefix] 107 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.BackOnPressed))] 108 | private static bool PlayerBackOnPressed(ref bool __result) 109 | { 110 | __result = ActionInputDefinitions.Cancel.ButtonDown; 111 | return false; 112 | } 113 | 114 | [HarmonyPrefix] 115 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.InteractOnPressed))] 116 | private static bool PlayerInteractOnPressed(ref bool __result) 117 | { 118 | __result = ActionInputDefinitions.Interact.ButtonDown; 119 | return false; 120 | } 121 | 122 | [HarmonyPrefix] 123 | [HarmonyPatch(typeof(PlayerInput), nameof(PlayerInput.InteractOnReleased))] 124 | private static bool PlayerInteractOnReleased(ref bool __result) 125 | { 126 | __result = ActionInputDefinitions.Interact.ButtonUp; 127 | return false; 128 | } 129 | } -------------------------------------------------------------------------------- /BendyVR_5/src/VrInput/VirtualKey.cs: -------------------------------------------------------------------------------- 1 | namespace BendyVR_5.VrInput; 2 | 3 | public struct VirtualKey 4 | { 5 | public const string Attack = "AttackButton"; 6 | public const string DialogUp = "DialogUpButton"; 7 | public const string DialogDown = "DialogDownButton"; 8 | public const string Jump = "JumpButton"; 9 | public const string Use = "UseButton"; 10 | public const string Run = "RunButton"; 11 | 12 | public const string Cancel = "CancelButton"; 13 | public const string Pause = "PauseButton"; 14 | public const string Confirm = "ConfirmButton"; 15 | public const string NextMenu = "NextMenuButton"; 16 | public const string PreviousMenu = "PreviousMenuButton"; 17 | public const string LookXAxisStick = "LookXAxis_Stick"; 18 | public const string MoveXAxis = "MoveXAxis"; 19 | public const string MoveYAxis = "MoveYAxis"; 20 | public const string MoveForwardKeyboard = "MoveForwardKeyboard"; 21 | public const string MoveBackwardKeyboard = "MoveBackwardKeyboard"; 22 | public const string StrafeLeftKeyboard = "StrafeLeftKeyboard"; 23 | public const string StrafeRightKeyboard = "StrafeRightKeyboard"; 24 | 25 | // These are unused in VR, since they can be done with gestures or menus. 26 | 27 | // These I don't know what they're for. 28 | public const string UIRightStickHorizontal = "UIRightStickHorizontal"; 29 | public const string UIRightStickVertical = "UIRightStickVertical"; 30 | public const string EndBracketKey = "EndBracketKey"; 31 | public const string UILeftStickHorizontal = "UILeftStickHorizontal"; 32 | public const string UILeftStickVertical = "UILeftStickVertical"; 33 | 34 | // These are mouse/keyboard only. 35 | public const string LookXAxisMouse = "LookXAxis_Mouse"; 36 | public const string LookYAxisMouse = "LookYAxis_Mouse"; 37 | 38 | // These I just don't need. 39 | public const string LookYAxisStick = "LookYAxis_Stick"; 40 | public const string ItemsLeftRight = "ItemsLeftRight"; 41 | public const string ItemsUpDown = "ItemsUpDown"; 42 | public const string QuickSave = "QuickSaveButton"; 43 | public const string QuickLoad = "QuickLoadButton"; 44 | public const string DialogSelectionScroll = "DialogSelectionScroll"; 45 | 46 | // These are leftover debug stuff, so no need to use them. 47 | public const string Num0 = "Num0"; 48 | public const string Num1 = "Num1"; 49 | public const string Num2 = "Num2"; 50 | public const string Num3 = "Num3"; 51 | public const string Num4 = "Num4"; 52 | public const string Num5 = "Num5"; 53 | public const string Num6 = "Num6"; 54 | public const string Num7 = "Num7"; 55 | public const string Num8 = "Num8"; 56 | public const string Num9 = "Num9"; 57 | public const string PeriodKey = "PeriodKey"; 58 | public const string PressDemo1 = "PressDemo1"; 59 | public const string PressDemo2 = "PressDemo2"; 60 | public const string PressDemo3 = "PressDemo3"; 61 | public const string PressDemo4 = "PressDemo4"; 62 | public const string TakeDebugScreenshot = "TakeDebugScreenshot"; 63 | 64 | // These are special cases, virtual keys created specifically for VR, just for the prompts. 65 | public const string Melee = "MeleeButton"; 66 | public const string ScrollUpDown = "ScrollUpDown"; 67 | } -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | F:\VRUnityModding\BendyVRInstall\Mod 5 | F:\VRUnityModding\BendyVRInstall\Mod\BepInEx 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Grant Bagwell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![Bendy VR](https://github.com/baggyg/BendyVR/blob/main/WebsiteAssets/BendyVRGithub.jpg) 2 | 3 | **Update (18/01/2023): Pico 3 / 4 - If you are using the Streaming Assistant, Pico are aware they have a problem with skeleton bindings. They have stated: 'skeleton will be added in streaming assistant version 9.4.*. This version will be released at the end of February'. In the meantime if you want to play on Pico you will need Virtual Desktop.** 4 | 5 | Bendy VR is a VR mod for [Bendy and the Ink Machine](https://store.steampowered.com/app/622650/Bendy_and_the_Ink_Machine/), with full motion control support. This is Team Beef's very first (of hopefully many) PCVR mods. 6 | 7 | I would firstly like to thank Raicuparta for the example and work he has already contributed to Flat2VR mods. Its fair to say that either BendyVR would not have existed without his VR mods or would have certainly taken a much longer time to create. Quite a few systems are based upon or using his work, including the Installer. Raicuparta has a slew of his own VR mods which you can browse [on his website](https://raicuparta.com/). 8 | 9 | ## Team Beef Patreon / Support Team Beef 10 | 11 | I would like to thank all of our patrons for supporting us. Without this support the VR mods we are working on would simply not be possible. If you like what we are doing, want to suggest and vote on new ports and get access to in-development versions please click the banner below 12 | 13 | [![Team Beef Patreon](https://github.com/baggyg/BendyVR/blob/main/WebsiteAssets/reddit_mobile_1280_384.jpg)](https://www.patreon.com/teambeef) 14 | 15 | ## Features 16 | 17 | - Motion controlled hands with melee combat 18 | - VR Comfort Options (Snap / Smooth Turn) 19 | - Support for Left Handed Users (Including Switch Sticks) 20 | - Countless game alterations to make this as fun as possible in VR 21 | 22 | ## How to Install 23 | 24 | **IMPORTANT - the Installer must be on the same drive as the game is installed** 25 | 26 | **Note: If you had a previous in-development version (Patreon version), firstly completely delete the "BepInEx" folder from your Steam BATIM folder and then follow the instructions below.** 27 | 28 | - [Download the latest release zip](https://github.com/baggyg/BendyVR/releases/latest). 29 | - Extract it somewhere safe (you need to keep this folder for the Mod to function). 30 | - Open 'TeamBeefInstaller.Exe' and click Install 31 | - Either Run the game as usual or by clicking the "Start Game" button in the Installer. 32 | 33 | ## Troubleshooting 34 | 35 | If anyone is having an issue with BendyVR install, please follow the below process: 36 | 37 | - first ensure the Mod files are on the same drive as the game itself. If not use the uninstall, move the files to the same drive (anywhere in the same drive), then click the install button again. 38 | - Ensure the BepInEx window starts when starting the game. If it doesn't then the links are wrong and check doorstop_config.ini from your game folder to see where it is looking and send this across. If there is any odd characters, this could be causing an issue and we suggest uninstalling (from the Installer), copying the mod to the root of that drive (I.e. C:/BendyInstall) and then installing again. 39 | - If BepInEx is working then send across any errors this shows (ideally a screenshot of the whole window) 40 | 41 | ## Requirements 42 | 43 | - A compatible version of Bendy and the Ink Machine. Currently that's version 1.1.2. This version is available in these stores: 44 | - [Steam](https://store.steampowered.com/app/622650/Bendy_and_the_Ink_Machine/) 45 | - A PC ready for PCVR. Bendy VR doesn't work on standalone VR platforms. 46 | - An OpenVR-compatible VR headset. Examples: 47 | - Quest 2 connected to the PC via Link Cable, Air Link, Virtual Desktop, ALVR, etc 48 | - Any Oculus Rift 49 | - Valve Index 50 | - Any Vive 51 | - Any Windows Mixed Reality device (probably?) 52 | - VR controllers. This isn't playable with a normal game controller, motion controls are required. 53 | - Steam and SteamVR installed. 54 | 55 | ## Controls 56 | 57 | I've attached a default SteamVR Input for each of the main PCVR headsets. However I was only able to test with Quest 2 (via Link / Air Link). You should be able to see the mapped controls via SteamInput and showing on the controllers. Please let me know if Vive Controllers or Knuckles work and if you have a better default binding, I'd love to have it. 58 | 59 | **Please note that in the menu there are no tracked hands. Use the UiUp / UiDown / Next / Previous / Confirm / Cancel to navigate.** 60 | 61 | Sample Oculus Touch Controls (Quest 2 / Rift S controls): 62 | 63 | **Non Dominant Hand:** 64 | 65 | Joystick = Move 66 | 67 | Joystick Click / Grip = Run 68 | 69 | Trigger = Interact (What you are interacting with is based on your non-dominant hand. Turn on the Laser sight from the Advanced Menu if you are unsure). 70 | 71 | Y = Pause 72 | 73 | **Dominant Hand:** 74 | 75 | Joystick Left / Right = Smooth Turn / Snap Turn 76 | 77 | B = Seeing Tool (CH5 / New Game+) 78 | 79 | A = Jump 80 | 81 | Trigger = Attack (Gun / Throw weapon types only) 82 | 83 | When you get the axe or other Melee weapon, it is motion controlled so swing to attack. 84 | 85 | ## VR Settings 86 | 87 | You can find VR Settings in the Advanced Menu (via Main Menu or Pause). 88 | 89 | ## Performance 90 | 91 | You want to aim to get a smooth framerate. The game will run best if you turn off all the optional effects (Anti-Aliasing / Depth of Field / Bloom / Ambient Occlusion), so you have quite a few options to get to a reasonable frame rate (in addition to the graphic quality setting and Steam resolution). 92 | 93 | Ambient Occlusion does have some small artifacts which are different in each eye. However all options do add nice graphics to the game. Depth of Field is especially heavy. 94 | 95 | Bendy VR ships with [openvr_fsr](https://github.com/fholger/openvr_fsr), which is already enabled on Ultra Quality Mode. To disable or adjust FSR , edit `\Bendy and the Ink Machine\Bendy and the Ink Machine_Data\Plugins\openvr_mod.cfg`. Check the [openvr_fsr readme](https://github.com/fholger/openvr_fsr#readme) for more details. 96 | 97 | ## Known Issues 98 | 99 | - Ending Cinematic is screen locked - this is due to the Unity Video Player used. 100 | - After the credits you have to exit game (and restart for new game + / archives). Your game will have been saved. 101 | - You cannot get back to the main menu from the pause menu. Clicking quit and then Confirm will exit the games completely. I will look to fix this in the future. 102 | - Fog / Some Other Post-Processing Effects rotate with view. Unfortuantely "allowRoll" was added in Unity Version (2018.3) BATIM uses 2018.2. 103 | - Some of the rising seems to follow your view. This is caused by the original developers using a "Cutout" masking to block of part of the mesh to present the appearnace of "moving ink". I can't decompile this shader so am unable to alter. 104 | 105 | ## How to Uninstall 106 | 107 | Open the TeamBeefInstaller.exe and click the Uninstall button. 108 | 109 | ## Support 110 | 111 | If you find bugs or are otherwise facing problems with the mod, please [open an issue](https://github.com/baggyg/BendyVR/issues/new/choose). 112 | 113 | You can also contact Team Beef on the [Team Beef Discord](https://discord.gg/fA6m8SMZPA). 114 | -------------------------------------------------------------------------------- /WebsiteAssets/BendyVRGithub.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baggyg/BendyVR/cf09cf4ecb4c37cf12b45af70854c5562ba5216b/WebsiteAssets/BendyVRGithub.jpg -------------------------------------------------------------------------------- /WebsiteAssets/reddit_mobile_1280_384.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baggyg/BendyVR/cf09cf4ecb4c37cf12b45af70854c5562ba5216b/WebsiteAssets/reddit_mobile_1280_384.jpg --------------------------------------------------------------------------------