/// <summary> /// Loads AssetBundles and populates the platforms array with CustomPlatform objects /// </summary> public CustomPlatform[] CreateAllPlatforms(Transform parent) { string customPlatformsFolderPath = Path.Combine(Environment.CurrentDirectory, customFolder); // Create the CustomPlatforms folder if it doesn't already exist if (!Directory.Exists(customPlatformsFolderPath)) { Directory.CreateDirectory(customPlatformsFolderPath); } // Find AssetBundles in our CustomPlatforms directory string[] allBundlePaths = Directory.GetFiles(customPlatformsFolderPath, "*.plat"); platforms = new List <CustomPlatform>(); bundlePaths = new List <string>(); // Create a dummy CustomPlatform for the original platform CustomPlatform defaultPlatform = new GameObject("Default Platform").AddComponent <CustomPlatform>(); defaultPlatform.transform.parent = parent; defaultPlatform.platName = "Default Environment"; defaultPlatform.platAuthor = "Beat Saber"; defaultPlatform.icon = Resources.FindObjectsOfTypeAll <Sprite>().Where(x => x.name == "LvlInsaneCover").FirstOrDefault(); platforms.Add(defaultPlatform); bundlePaths.Add(""); // Populate the platforms array for (int i = 0; i < allBundlePaths.Length; i++) { CustomPlatform newPlatform = LoadPlatformBundle(allBundlePaths[i], parent); } return(platforms.ToArray()); }
/// <summary> /// Changes to a specific <see cref="CustomPlatform"/> /// </summary> /// <param name="platform">The <see cref="CustomPlatform"/> to change to</param> public async Task ChangeToPlatformAsync(CustomPlatform platform) { if (platform == _platformManager.ActivePlatform) { return; } _cancellationTokenSource?.Cancel(); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); CancellationToken token = _cancellationTokenSource.Token; DestroyPlatform(_platformManager.ActivePlatform.gameObject); if (platform == _platformManager.RandomPlatform) { platform = RandomPlatform; } _platformManager.ActivePlatform = platform; if (platform.isDescriptor) { platform = await ReplaceDescriptorAsync(platform); } if (token.IsCancellationRequested) { return; } _platformManager.ActivePlatform = platform; _siraLog.Debug($"Switching to {platform.name}"); _environmentHider.HideObjectsForPlatform(platform); SpawnPlatform(platform.gameObject); }
public CustomPlatform LoadPlatformBundle(string bundlePath, Transform parent) { AssetBundle bundle = AssetBundle.LoadFromFile(bundlePath); if (bundle == null) { return(null); } CustomPlatform newPlatform = LoadPlatform(bundle, parent); if (newPlatform != null) { bundlePaths.Add(bundlePath); platforms.Add(newPlatform); } using (var md5 = MD5.Create()) { using (var stream = File.OpenRead(bundlePath)) { byte[] hash = md5.ComputeHash(stream); newPlatform.platHash = BitConverter .ToString(hash) .Replace("-", string.Empty) .ToLower(); } } return(newPlatform); }
/// <summary> /// Instantiates a platform from an assetbundle. /// </summary> /// <param name="bundle">An AssetBundle containing a CustomPlatform</param> /// <param name="parent">The <see cref="Transform"/> under which this <paramref name="bundle"/> will be instantiated</param> /// <returns></returns> private static CustomPlatform LoadPlatform(AssetBundle bundle, Transform parent) { GameObject platformPrefab = bundle.LoadAsset <GameObject>("_CustomPlatform"); if (platformPrefab == null) { return(null); } GameObject newPlatform = UnityEngine.Object.Instantiate(platformPrefab.gameObject); try { foreach (AudioListener al in FindAll <AudioListener>(newPlatform)) { UnityEngine.Object.DestroyImmediate(al); } } catch (ComponentNotFoundException) { } newPlatform.transform.parent = parent; bundle.Unload(false); // Collect author and name CustomPlatform customPlatform = newPlatform.GetComponent <CustomPlatform>(); if (customPlatform == null) { // Check for old platform global::CustomPlatform legacyPlatform = newPlatform.GetComponent <global::CustomPlatform>(); if (legacyPlatform != null) { // Replace legacyplatform component with up to date one customPlatform = newPlatform.AddComponent <CustomPlatform>(); customPlatform.platName = legacyPlatform.platName; customPlatform.platAuthor = legacyPlatform.platAuthor; customPlatform.hideDefaultPlatform = true; // Remove old platform data GameObject.Destroy(legacyPlatform); } else { // no customplatform component, abort GameObject.Destroy(newPlatform); return(null); } } newPlatform.name = customPlatform.platName + " by " + customPlatform.platAuthor; if (customPlatform.icon == null) { customPlatform.icon = Resources.FindObjectsOfTypeAll <Sprite>().Where(x => x.name == "FeetIcon").FirstOrDefault(); } newPlatform.SetActive(false); return(customPlatform); }
/// <summary> /// The callback executed when a platform is successfully loaded /// </summary> internal void HandlePlatformLoaded(CustomPlatform platform, string fullPath) { CustomPlatform newPlatform = Instantiate(platform); newPlatform.name = platform.name; newPlatform.fullPath = platform.fullPath; newPlatform.platHash = platform.platHash; newPlatform.transform.parent = transform; if (newPlatform.icon == null) { newPlatform.icon = fallbackCover; } CheckLastSelectedPlatform(ref newPlatform); if (_platformLoader.platformFilePaths.ContainsKey(fullPath)) { int index = allPlatforms.IndexOf(_platformLoader.platformFilePaths[fullPath]); allPlatforms.RemoveAt(index); if (activePlatform == _platformLoader.platformFilePaths[fullPath]) { activePlatform = newPlatform; } Destroy(_platformLoader.platformFilePaths[fullPath].gameObject); _platformLoader.platformFilePaths[fullPath] = newPlatform; allPlatforms.Insert(index, newPlatform); } else { _platformLoader.platformFilePaths.Add(fullPath, newPlatform); allPlatforms.Add(newPlatform); } }
internal static void InternalTempChangeToPlatform(int index) { if (!GetCurrentEnvironment().name.StartsWith("Menu")) { platformSpawned = true; } Plugin.Log("switching to " + Instance.GetPlatform(index)); // Hide current Platform activePlatform.gameObject.SetActive(false); int oldIndex = platformIndex; // Increment index platformIndex = index % platforms.Length; // Save active platform activePlatform = currentPlatform; platformIndex = oldIndex; // Show new platform activePlatform.gameObject.SetActive(true); // Hide environment for new platform Instance.StartCoroutine(HideForPlatformAfterOneFrame(activePlatform)); // Update lightSwitchEvent TubeLight references TubeLightManager.UpdateEventTubeLightList(); }
/// <summary> /// IEnumertor version of HideObjectsForPlatform /// Required for compatibility with BS v0.11.2 because of Async /// scene loading. /// </summary> /// <param name="platform">A platform that defines which objects are to be hidden</param> public IEnumerator WaitForPlatformAndHideObjects(CustomPlatform platform) { yield return(new WaitUntil(() => Resources.FindObjectsOfTypeAll <GameObject>() .Any(x => x.name == "MenuPlayersPlace" || x.name == "PlayersPlace"))); HideObjectsForPlatform(platform); }
/// <summary> /// Instantiate a platform from an assetbundle. /// </summary> /// <param name="bundle">An AssetBundle containing a CustomPlatform</param> /// <returns></returns> private CustomPlatform LoadPlatform(AssetBundle bundle, Transform parent) { GameObject platformPrefab = bundle.LoadAsset <GameObject>("_CustomPlatform"); if (platformPrefab == null) { Plugin.logger.Info("Assetbundle didnt contain a Custom Platform"); return(null); } GameObject newPlatform = GameObject.Instantiate(platformPrefab.gameObject); newPlatform.transform.parent = parent; bundle.Unload(false); // Collect author and name CustomPlatform customPlatform = newPlatform.GetComponent <CustomPlatform>(); if (customPlatform == null) { // Check for old platform global::CustomPlatform legacyPlatform = newPlatform.GetComponent <global::CustomPlatform>(); if (legacyPlatform != null) { Plugin.logger.Info("legacy version of customPlatform detected, updating"); // Replace legacyplatform component with up to date one customPlatform = newPlatform.AddComponent <CustomPlatform>(); customPlatform.platName = legacyPlatform.platName; customPlatform.platAuthor = legacyPlatform.platAuthor; customPlatform.hideDefaultPlatform = true; // Remove old platform data GameObject.Destroy(legacyPlatform); } else { // no customplatform component, abort Plugin.logger.Info("Loaded object had no customplatform attached, skipping"); GameObject.Destroy(newPlatform); return(null); } } newPlatform.name = customPlatform.platName + " by " + customPlatform.platAuthor; if (customPlatform.icon == null) { customPlatform.icon = Resources.FindObjectsOfTypeAll <Sprite>().Where(x => x.name == "FeetIcon").FirstOrDefault(); } AddManagers(newPlatform); newPlatform.gameObject.SetActive(false); return(customPlatform); }
/// <summary> /// Allows dynamic loading of <see cref="CustomPlatform"/>s from files. /// </summary> /// <param name="path">The path of file containing the <see cref="CustomPlatform"/></param> /// <returns>The reference to the loaded <see cref="CustomPlatform"/></returns> public static CustomPlatform AddPlatform(string path) { CustomPlatform newPlatform = PlatformLoader.LoadPlatformBundle(path, Anchor.transform); if (newPlatform != null) { AllPlatforms.Add(newPlatform); } return(newPlatform); }
public override TableCell CellForIdx(TableView t, int idx) { CustomPlatform platform = PlatformManager.Instance.GetPlatform(idx); LevelListTableCell _tableCell = GetTableCell(false); _tableCell.GetPrivateField <TextMeshProUGUI>("_songNameText").text = platform.platName; _tableCell.GetPrivateField <TextMeshProUGUI>("_authorText").text = platform.platAuthor; _tableCell.GetPrivateField <UnityEngine.UI.RawImage>("_coverRawImage").texture = platform.icon != null? platform.icon.texture : UnityEngine.Texture2D.blackTexture; _tableCell.reuseIdentifier = "PlatformListCell"; return(_tableCell); }
public CustomPlatform AddPlatform(string path) { CustomPlatform newPlatform = platformLoader.LoadPlatformBundle(path, transform); if (newPlatform != null) { var platList = platforms.ToList(); platList.Add(newPlatform); platforms = platList.ToArray(); } return(newPlatform); }
public override TableCell CellForIdx(int idx) { CustomPlatform platform = PlatformManager.Instance.GetPlatform(idx); LevelListTableCell _tableCell = GetTableCell(idx, false); _tableCell.GetPrivateField <TextMeshProUGUI>("_songNameText").text = platform.platName; _tableCell.GetPrivateField <TextMeshProUGUI>("_authorText").text = platform.platAuthor; _tableCell.GetPrivateField <UnityEngine.UI.Image>("_coverImage").sprite = platform.icon; _tableCell.reuseIdentifier = "PlatformListCell"; return(_tableCell); }
public TableCell CellForRow(int row) { StandardLevelListTableCell _tableCell = Instantiate(_songListTableCellInstance); CustomPlatform platform = PlatformLoader.Instance.GetPlatform(row); _tableCell.songName = platform.platName; _tableCell.author = platform.platAuthor; _tableCell.coverImage = platform.icon; return(_tableCell); }
private async Task <CustomPlatform> ReplaceDescriptorAsync(CustomPlatform descriptor) { CustomPlatform?platform = await _platformManager.CreatePlatformAsync(descriptor.fullPath); if (platform is null) { return(_platformManager.DefaultPlatform); } _platformManager.AllPlatforms.Replace(descriptor, platform); UnityEngine.Object.Destroy(descriptor.gameObject); return(platform); }
/// <summary> /// Hide and unhide world objects as required by a platform /// </summary> /// <param name="platform">A platform that defines which objects are to be hidden</param> public void HideObjectsForPlatform(CustomPlatform platform) { FindEnvironment(); if (feet != null) { SetCollectionHidden(feet, (platform.hideDefaultPlatform && !showFeetOverride)); } if (originalPlatform != null) { SetCollectionHidden(originalPlatform, platform.hideDefaultPlatform); } if (smallRings != null) { SetCollectionHidden(smallRings, platform.hideSmallRings); } if (bigRings != null) { SetCollectionHidden(bigRings, platform.hideBigRings); } if (visualizer != null) { SetCollectionHidden(visualizer, platform.hideEQVisualizer); } if (towers != null) { SetCollectionHidden(towers, platform.hideTowers); } if (highway != null) { SetCollectionHidden(highway, platform.hideHighway); } if (backColumns != null) { SetCollectionHidden(backColumns, platform.hideBackColumns); } if (backLasers != null) { SetCollectionHidden(backLasers, platform.hideBackLasers); } if (doubleColorLasers != null) { SetCollectionHidden(doubleColorLasers, platform.hideDoubleColorLasers); } if (rotatingLasers != null) { SetCollectionHidden(rotatingLasers, platform.hideRotatingLasers); } if (trackLights != null) { SetCollectionHidden(trackLights, platform.hideTrackLights); } }
public TableCell CellForRow(int row) { LevelListTableCell _tableCell = Instantiate(_songListTableCellInstance); CustomPlatform platform = PlatformManager.Instance.GetPlatform(row); _tableCell.songName = platform.platName; _tableCell.author = platform.platAuthor; _tableCell.coverImage = platform.icon; _tableCell.reuseIdentifier = "PlatformListCell"; return(_tableCell); }
/// <summary> /// Adds managers to a <see cref="CustomPlatform"/> /// </summary> /// <param name="customPlatform">The <see cref="CustomPlatform"/> for which to spawn managers</param> private void AddManagers(CustomPlatform customPlatform) { GameObject go = customPlatform.gameObject; bool active = go.activeSelf; if (active) { go.SetActive(false); } AddManagers(go, go); if (active) { go.SetActive(true); } }
/// <summary> /// Restores the last platform selection /// </summary> private void LastSelectedPlatform(CustomPlatform platform) { if (platform.fullPath == _config.SingleplayerPlatformPath) { SingleplayerPlatform = platform; } if (platform.fullPath == _config.MultiplayerPlatformPath) { MultiplayerPlatform = platform; } if (platform.fullPath == _config.A360PlatformPath) { A360Platform = platform; } }
/// <summary> /// Sets the platforms that were last selected as the current ones /// </summary> internal void CheckLastSelectedPlatform(ref CustomPlatform platform) { if (_config.SingleplayerPlatformPath == platform.platName + platform.platAuthor) { currentSingleplayerPlatform = platform; } if (_config.MultiplayerPlatformPath == platform.platName + platform.platAuthor) { currentMultiplayerPlatform = platform; } if (_config.A360PlatformPath == platform.platName + platform.platAuthor) { currentA360Platform = platform; } }
/// <summary> /// Waits until the enviornment loads in order to find it reliably. /// This calls HideObjectsForPlatforms because they are always used together. /// Required for BS v0.11.2 because of Async Scene Loading. /// </summary> /// <param name="platform">A platform that defines which objects are to be hidden</param> public IEnumerator WaitForAndFindEnvironment(CustomPlatform platform) { Console.WriteLine("waiting for load."); yield return(new WaitUntil(() => Resources.FindObjectsOfTypeAll <GameObject>() .Any(x => x.name == "MenuPlayersPlace" || x.name == "PlayersPlace"))); yield return(new WaitForSeconds(0.2f)); //Waits for ~12 frames after the platform is loaded to make sure everything is ready to grab. I got lazy. Console.WriteLine("Load complete."); FindEnvironment(); Console.WriteLine("ENV found."); HideObjectsForPlatform(platform); }
/// <summary> /// Asynchronously creates a <see cref="CustomPlatform"/> by loading an <see cref="AssetBundle"/> from the given <paramref name="fullPath"/> /// </summary> public async Task <CustomPlatform?> CreatePlatformAsync(string fullPath) { CustomPlatform?platform = await _platformLoader.LoadPlatformFromFileAsync(fullPath); if (platform is null) { return(null); } CustomPlatform newPlatform = Object.Instantiate(platform, _anchor); Object.Destroy(platform.gameObject); newPlatform.name = platform.name; newPlatform.isDescriptor = false; LastSelectedPlatform(newPlatform); return(newPlatform); }
/// <summary> /// Decide which platform to change to based on the type of the <see cref="ScenesTransitionSetupDataSO"/> /// </summary> // ReSharper disable once AsyncVoidMethod internal async void OnTransitionDidFinish(ScenesTransitionSetupDataSO?setupData, DiContainer container) { CustomPlatform platform = setupData switch { MenuScenesTransitionSetupDataSO or null when _lobbyGameStateModel.gameState == MultiplayerGameState.None => _platformManager.MenuPlatform, StandardLevelScenesTransitionSetupDataSO when _platformManager.APIRequestedPlatform is not null => _platformManager.APIRequestedPlatform, StandardLevelScenesTransitionSetupDataSO standardLevelScenesTransitionSetupDataSO when standardLevelScenesTransitionSetupDataSO.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.requires360Movement => _platformManager.A360Platform, StandardLevelScenesTransitionSetupDataSO or MissionLevelScenesTransitionSetupDataSO or TutorialScenesTransitionSetupDataSO => _platformManager.SingleplayerPlatform, MultiplayerLevelScenesTransitionSetupDataSO when container.HasBinding <MultiplayerLocalActivePlayerFacade>() => _platformManager.MultiplayerPlatform, _ => _platformManager.DefaultPlatform }; _container = container; _environmentHider.OnTransitionDidFinish(setupData, container); await ChangeToPlatformAsync(platform); }
/// <summary> /// Changes to a specific <see cref="CustomPlatform"/> /// </summary> /// <param name="platform">The <see cref="CustomPlatform"/> to change to</param> public async Task ChangeToPlatformAsync(CustomPlatform platform) { try { if (platform == _platformManager.ActivePlatform) { return; } _cancellationTokenSource?.Cancel(); _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = _cancellationTokenSource.Token; DestroyCustomObjects(); _platformManager.ActivePlatform.gameObject.SetActive(false); _platformManager.ActivePlatform = platform; if (platform.isDescriptor) { CustomPlatform?newPlatform = await _platformManager.CreatePlatformAsync(platform.fullPath); if (newPlatform is not null) { _platformManager.AllPlatforms.Replace(platform, newPlatform); UnityEngine.Object.Destroy(platform.gameObject); } cancellationToken.ThrowIfCancellationRequested(); if (newPlatform is null) { _ = ChangeToPlatformAsync(_platformManager.DefaultPlatform); return; } _platformManager.ActivePlatform = newPlatform; } _siraLog.Info($"Switching to {_platformManager.ActivePlatform.name}"); _environmentHider.HideObjectsForPlatform(_platformManager.ActivePlatform); _platformManager.ActivePlatform.gameObject.SetActive(true); SpawnCustomObjects(); } catch (OperationCanceledException) { } }
/// <summary> /// Notifies a given <see cref="CustomPlatform"/> when it gets activated or deactivated /// </summary> /// <param name="customPlatform">What <see cref="CustomPlatform"/> to notify</param> /// <param name="type">What happened to the platform</param> private static void NotifyPlatform(CustomPlatform customPlatform, NotifyType type) { NotifyOnEnableOrDisable[] things = customPlatform?.gameObject?.GetComponentsInChildren <NotifyOnEnableOrDisable>(true); if (things != null) { foreach (NotifyOnEnableOrDisable thing in things) { if (type == NotifyType.Disable) { thing.PlatformDisabled(); } else { thing.PlatformEnabled(); } } } }
/// <summary> /// Loads AssetBundles and populates the platforms array with CustomPlatform objects /// </summary> public static List <CustomPlatform> CreateAllPlatforms(Transform parent) { string customPlatformsFolderPath = Path.Combine(Environment.CurrentDirectory, FOLDER); // Create the CustomPlatforms folder if it doesn't already exist if (!Directory.Exists(customPlatformsFolderPath)) { Directory.CreateDirectory(customPlatformsFolderPath); } // Find AssetBundles in our CustomPlatforms directory string[] allBundlePaths = Directory.GetFiles(customPlatformsFolderPath, "*.plat"); List <CustomPlatform> platforms = new List <CustomPlatform>(); // Create a dummy CustomPlatform for the original platform CustomPlatform defaultPlatform = new GameObject("Default Platform").AddComponent <CustomPlatform>(); defaultPlatform.transform.parent = parent; defaultPlatform.platName = "Default Environment"; defaultPlatform.platAuthor = "Beat Saber"; Texture2D texture = Resources.FindObjectsOfTypeAll <Texture2D>().First(x => x.name == "LvlInsaneCover"); defaultPlatform.icon = Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), new Vector2(0.5f, 0.5f)); platforms.Add(defaultPlatform); // Populate the platforms array Log("[START OF PLATFORM LOADING SPAM]-------------------------------------"); int j = 0; for (int i = 0; i < allBundlePaths.Length; i++) { j++; CustomPlatform newPlatform = LoadPlatformBundle(allBundlePaths[i], parent); if (newPlatform != null) { platforms.Add(newPlatform); } } Log("[END OF PLATFORM LOADING SPAM]---------------------------------------"); // Replace materials for all renderers MaterialSwapper.ReplaceMaterials(SCENE); return(platforms); }
/// <summary> /// Hide and unhide world objects as required by a platform /// </summary> /// <param name="platform">A platform that defines which objects are to be hidden</param> public void HideObjectsForPlatform(CustomPlatform platform) { Console.WriteLine("Hiding env for: " + platform.platName); SetCollectionHidden(feet, (platform.hideDefaultPlatform && !showFeetOverride)); SetCollectionHidden(originalPlatform, platform.hideDefaultPlatform); SetCollectionHidden(smallRings, platform.hideSmallRings); SetCollectionHidden(bigRings, platform.hideBigRings); SetCollectionHidden(visualizer, platform.hideEQVisualizer); SetCollectionHidden(towers, platform.hideTowers); SetCollectionHidden(highway, platform.hideHighway); SetCollectionHidden(backColumns, platform.hideBackColumns); SetCollectionHidden(backLasers, platform.hideBackLasers); SetCollectionHidden(doubleColorLasers, platform.hideDoubleColorLasers); SetCollectionHidden(rotatingLasers, platform.hideRotatingLasers); SetCollectionHidden(trackLights, platform.hideTrackLights); Console.WriteLine("Environment hidden"); }
/// <summary> /// Restores the last platform selection /// </summary> private void LastSelectedPlatform(CustomPlatform platform) { if (platform.platHash == _config.SingleplayerPlatformHash) { SingleplayerPlatform = platform; } if (platform.platHash == _config.MultiplayerPlatformHash) { MultiplayerPlatform = platform; } if (platform.platHash == _config.A360PlatformHash) { A360Platform = platform; } if (platform.platHash == _config.MenuPlatformHash) { MenuPlatform = platform; } }
public CustomPlatform LoadPlatformBundle(string bundlePath, Transform parent) { AssetBundle bundle = AssetBundle.LoadFromFile(bundlePath); if (bundle == null) { return(null); } CustomPlatform newPlatform = LoadPlatform(bundle, parent); if (newPlatform != null) { bundlePaths.Add(bundlePath); platforms.Add(newPlatform); Plugin.logger.Info("Loaded: " + newPlatform.name); } return(newPlatform); }
internal static CustomPlatform LoadPlatformBundle(string bundlePath, Transform parent) { AssetBundle bundle = AssetBundle.LoadFromFile(bundlePath); if (bundle == null) { return(null); } CustomPlatform newPlatform = LoadPlatform(bundle, parent); using var md5 = MD5.Create(); using var stream = File.OpenRead(bundlePath); byte[] hash = md5.ComputeHash(stream); newPlatform.platHash = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant(); return(newPlatform); }
/// <summary> /// Loads AssetBundles and populates the platforms array with CustomPlatform objects /// </summary> private void CreateAllPlatforms() { string customPlatformsFolderPath = Path.Combine(Environment.CurrentDirectory, customFolder); // Create the CustomPlatforms folder if it doesn't already exist if (!Directory.Exists(customPlatformsFolderPath)) { Directory.CreateDirectory(customPlatformsFolderPath); } // Find AssetBundles in our CustomPlatforms directory string[] allBundlePaths = Directory.GetFiles(customPlatformsFolderPath, "*.plat"); platforms = new List <CustomPlatform>(); bundlePaths = new List <string>(); // Create a dummy CustomPlatform for the original platform CustomPlatform defaultPlatform = new GameObject("Default Platform").AddComponent <CustomPlatform>(); defaultPlatform.transform.parent = transform; defaultPlatform.platName = "Default Environment"; defaultPlatform.platAuthor = "Beat Saber"; defaultPlatform.icon = Resources.FindObjectsOfTypeAll <Sprite>().Where(x => x.name == "InsaneCover").FirstOrDefault(); platforms.Add(defaultPlatform); bundlePaths.Add(""); // Populate the platforms array for (int i = 0; i < allBundlePaths.Length; i++) { AssetBundle bundle = AssetBundle.LoadFromFile(allBundlePaths[i]); Log("Loading: " + Path.GetFileName(allBundlePaths[i])); CustomPlatform newPlatform = LoadPlatform(bundle); if (newPlatform != null) { platforms.Add(newPlatform); bundlePaths.Add(allBundlePaths[i]); Log("Loaded: " + newPlatform.name); } } }