using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using TMPro; public static class VRBeatSaberSceneBuilder { private const string MenuScene = "Assets/VRBeatsKit/Scenes/Menu.unity"; private const string SongCreatorDest = "Assets/Scenes/SongCreator.unity"; // ───────────────────────────────────────────── // ⓪ Fix — Set Graphics API to D3D11 (Oculus requirement) // ───────────────────────────────────────────── [MenuItem("Tools/VRBeatSaber/⓪ Fix — Set Graphics API to D3D11")] public static void FixGraphicsAPI() { var d3d11 = new[] { GraphicsDeviceType.Direct3D11 }; PlayerSettings.SetUseDefaultGraphicsAPIs(BuildTarget.StandaloneWindows, false); PlayerSettings.SetUseDefaultGraphicsAPIs(BuildTarget.StandaloneWindows64, false); PlayerSettings.SetGraphicsAPIs(BuildTarget.StandaloneWindows, d3d11); PlayerSettings.SetGraphicsAPIs(BuildTarget.StandaloneWindows64, d3d11); Debug.Log("[SceneBuilder] ✓ Graphics API set to Direct3D11 for Windows."); } [MenuItem("Tools/VRBeatSaber/⓪ Fix — Allow HTTP connections")] public static void FixAllowHttp() { PlayerSettings.insecureHttpOption = InsecureHttpOption.AlwaysAllowed; Debug.Log("[SceneBuilder] ✓ Insecure HTTP connections allowed."); } // ───────────────────────────────────────────── // Fix — Remove missing script components from open scene // ───────────────────────────────────────────── [MenuItem("Tools/VRBeatSaber/Fix — Remove Missing Scripts (open scene)")] public static void RemoveMissingScripts() { int removed = 0; foreach (var go in Object.FindObjectsByType(FindObjectsSortMode.None)) { var so = new SerializedObject(go); var components = so.FindProperty("m_Component"); for (int i = components.arraySize - 1; i >= 0; i--) { var comp = components.GetArrayElementAtIndex(i) .FindPropertyRelative("component") .objectReferenceValue; if (comp == null) { components.DeleteArrayElementAtIndex(i); removed++; } } so.ApplyModifiedPropertiesWithoutUndo(); } var activeScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); EditorSceneManager.MarkSceneDirty(activeScene); Debug.Log($"[SceneBuilder] ✓ Removed {removed} missing script(s) from '{activeScene.name}'."); } // ───────────────────────────────────────────── // ① Menu — Add Song Creator Button // ───────────────────────────────────────────── [MenuItem("Tools/VRBeatSaber/① Menu — Add Song Creator Button")] public static void PatchMenuAddSongCreatorButton() { var scene = EditorSceneManager.OpenScene(MenuScene, OpenSceneMode.Single); var settings = GameObject.Find("Settings"); if (settings == null) { Debug.LogError("[SceneBuilder] 'Settings' not found."); return; } if (settings.transform.Find("BG/Song Creator") != null) { Debug.LogWarning("[SceneBuilder] Button already exists."); return; } var bg = settings.transform.Find("BG"); if (bg == null) { Debug.LogError("[SceneBuilder] 'Settings/BG' not found."); return; } var btnGO = CreateStyledButton(bg, "Song Creator", new Vector2(0f, -20f), new Vector2(80f, 14f), 8f); var loader = btnGO.AddComponent(); InjectPrivate(loader, "button", btnGO.GetComponent