Esempio n. 1
0
        private static IEnumerator SetGoodRateChart_Process()
        {
            yield return(new WaitForEndOfFrame());

            Log.Write("SetFloatingDisplay Start");

            Vector3 ChartStandardLevelPosition = new Vector3(0, 0.25f, 2.25f); /* Original: 0, -0.4, 2.25 */
            Vector3 ChartStandardLevelRotation = new Vector3(35, 0, 0);

            var pos = ChartStandardLevelPosition;
            var rot = Quaternion.Euler(ChartStandardLevelRotation);

            floatingScreenForScore = FloatingScreen.CreateFloatingScreen(new Vector2(105, 65), false, pos, rot);

            floatingScreenForScore.SetRootViewController(BeatSaberUI.CreateViewController <GoodRateViewController>(), true);

            Image image = floatingScreenForScore.GetComponent <Image>();

            image.enabled = false;

            GraphContainer graph = floatingScreenForScore.gameObject.AddComponent <GraphContainer>();

            floatingScreenForScore.rootViewController.gameObject.SetActive(false);
            graph.gameObject.SetActive(false);
        }
Esempio n. 2
0
        private static IEnumerator SetDiaryView_Process()
        {
            yield return(new WaitForEndOfFrame());

            BeatSaberDiary.Log.Write("SetDiaryView Start");

            var screenSystem = Resources.FindObjectsOfTypeAll <ScreenSystem>()[0];
            //Vector3 pos = new Vector3(8.5f, 1.6f, 0.5f);
            //Vector3 rot = new Vector3(0, 90, 0);
            Vector3    pos = screenSystem.rightScreen.gameObject.transform.position;
            Quaternion rot = screenSystem.rightScreen.gameObject.transform.rotation;

            BeatSaberDiary.Log.Write("pos = " + pos);
            BeatSaberDiary.Log.Write("rot = " + rot);

            //[ERROR @ 16:36:11 | BeatSaberDialy] pos = (4.5, 1.6, 0.5)
            //[ERROR @ 16:36:11 | BeatSaberDialy] rot = (0.0, 120.0, 0.0)

            var floatingScreenForDiary = FloatingScreen.CreateFloatingScreen(new Vector2(150, 100), false, pos + new Vector3(0, 0, -0.05f), rot);

            floatingScreenForDiary.SetRootViewController(BeatSaberUI.CreateViewController <DiaryViewController>(), true);

            var createdController = Resources.FindObjectsOfTypeAll <DiaryViewController>()[0];

            createdController.parent          = floatingScreenForDiary;
            createdController.diaryController = Resources.FindObjectsOfTypeAll <BeatSaberDiaryController>()[0];
        }
 private void BSEvents_earlyMenuSceneLoadedFresh(ScenesTransitionSetupDataSO obj)
 {
     if (MuteButtonScreen != null)
     {
         GameObject.Destroy(MuteButtonScreen.gameObject);
         MuteButtonScreen = null;
     }
 }
Esempio n. 4
0
        public void ShowJoinRequest(User user)
        {
            FloatingScreen screen = FloatingScreen.CreateFloatingScreen(new Vector2(100, 50), true, new Vector3(0f, 0.9f, 2.4f), Quaternion.Euler(30f, 0f, 0f));

            DiscordAskToJoinView discordView = BeatSaberUI.CreateViewController <DiscordAskToJoinView>();

            discordView.user = user;

            screen.SetRootViewController(discordView, false);
        }
Esempio n. 5
0
 public MusicPlayer(HierarchyManager hierarchyManager)
 {
     _screenSystem    = hierarchyManager.GetField <ScreenSystem, HierarchyManager>("_screenSystem");
     _floatingScreen  = FloatingScreen.CreateFloatingScreen(new Vector2(120f, 35f), false, Vector3.zero, Quaternion.identity);
     _musicPlayerView = BeatSaberUI.CreateViewController <MusicPlayerView>();
     _floatingScreen.SetRootViewController(_musicPlayerView, true);
     _floatingScreen.transform.SetParent(_screenSystem.transform, false);
     _floatingScreen.transform.localPosition = new Vector3(-2.08f, 2.8f, 1.45f);
     _floatingScreen.transform.localRotation = Quaternion.Euler(new Vector3(335f, 300f, 0f));
 }
Esempio n. 6
0
        public void ShowInvite(User user, Activity activity)
        {
            FloatingScreen screen = FloatingScreen.CreateFloatingScreen(new Vector2(100, 50), true, new Vector3(0f, 0.9f, 2.4f), Quaternion.Euler(30f, 0f, 0f));

            DiscordInviteResponseView discordView = BeatSaberUI.CreateViewController <DiscordInviteResponseView>();

            discordView.user     = user;
            discordView.activity = activity;

            screen.SetRootViewController(discordView, false);
        }
Esempio n. 7
0
        public void Initialize()
        {
            _floatingScreen = FloatingScreen.CreateFloatingScreen(new Vector2(150f, 50f), false, _clockSettings.Position, Quaternion.Euler(_clockSettings.Rotation));
            _floatingScreen.GetComponent <VRGraphicRaycaster>().SetField("_physicsRaycaster", _physicsRaycasterWithCache);
            //_floatingScreen.GetComponent<Image>().enabled = false;
            _floatingScreen.SetRootViewController(_basicClockView, HMUI.ViewController.AnimationType.Out);

            _disabled = !_clockSettings.Enabled;
            _clockSettings.MarkDirty();
            ClockController_DateUpdated(DateTime.Now);
            _clockController.DateUpdated += ClockController_DateUpdated;
        }
        public void Initialize()
        {
            floatingScreen = FloatingScreen.CreateFloatingScreen(new Vector2(75, 25), false, new Vector3(0f, 0.2f, 2.5f), new Quaternion(0, 0, 0, 0));
            floatingScreen.transform.eulerAngles = new Vector3(60, 0, 0);
            floatingScreen.transform.localScale  = new Vector3(0.03f, 0.03f, 0.03f);

            BSMLParser.instance.Parse(BeatSaberMarkupLanguage.Utilities.GetResourceContent(Assembly.GetExecutingAssembly(), "PlaylistManager.UI.Views.FoldersView.bsml"), floatingScreen.gameObject, this);
            rootTransform.gameObject.SetActive(false);
            rootTransform.gameObject.name = "PlaylistManagerFoldersView";

            LevelFilteringNavigationController_ShowPacksInChildController.AllPacksViewSelectedEvent += LevelFilteringNavigationController_ShowPacksInChildController_AllPacksViewSelectedEvent;
        }
 public override void Initialize()
 {
     if (practiceMode)
     {
         base.Initialize();
         floatingScreen = FloatingScreen.CreateFloatingScreen(new Vector2(120, 55), false, new Vector3(0, 0, 0), new Quaternion(0, 0, 0, 0), curvatureRadius: 150);
         floatingScreen.transform.SetParent(pauseMenuManager.transform.Find("Wrapper").Find("MenuWrapper").Find("Canvas").Find("MainBar"));
         UpdateScreenPosition();
         BSMLParser.instance.Parse(BeatSaberMarkupLanguage.Utilities.GetResourceContent(Assembly.GetExecutingAssembly(), "ControllerTweaks.UI.Views.ControllerOffsetView.bsml"), floatingScreen.gameObject, this);
         pauseMenuManager.didPressContinueButtonEvent += PauseMenuManager_didPressContinueButtonEvent;
         controllerOffsetSettingsModalController.screenPositionChanged += UpdateScreenPosition;
     }
 }
        public FloatingScreen CreateFloatingScreen()
        {
            FloatingScreen screen = FloatingScreen.CreateFloatingScreen(
                new Vector2(20, 10), false,
                PluginConfig.Instance.ScreenPos,
                PluginConfig.Instance.ScreenRot);

            screen.HandleReleased -= OnRelease;
            screen.HandleReleased += OnRelease;

            GameObject.DontDestroyOnLoad(screen.gameObject);
            return(screen);
        }
 public void ShowMuteWindow()
 {
     if (MuteButtonScreen == null)
     {
         MuteButtonScreen = CreateFloatingScreen();
         MuteButtonWindow = BeatSaberUI.CreateViewController <MuteButtonWindow>();
         MuteButtonWindow.ParentCoordinator = this;
         MuteButtonScreen.SetRootViewController(MuteButtonWindow, HMUI.ViewController.AnimationType.None);
         AttachEvents();
     }
     MuteButtonScreen.gameObject.SetActive(true);
     MuteButtonWindow.UpdateMutebtnText();
 }
        public void Cleanup()
        {
            BSEvents.earlyMenuSceneLoadedFresh -= BSEvents_earlyMenuSceneLoadedFresh;
            BSEvents.menuSceneActive           -= OnSongExited;
            BSEvents.gameSceneActive           -= OnSongStarted;
            BSEvents.songPaused   -= OnGamePause;
            BSEvents.songUnpaused -= OnGameResume;

            if (MuteButtonScreen != null)
            {
                GameObject.Destroy(MuteButtonScreen.gameObject);
                MuteButtonScreen = null;
            }
        }
Esempio n. 13
0
        private static IEnumerator SetDiaryButton_Process()
        {
            yield return(new WaitForEndOfFrame());

            Log.Write("SetDiaryButton Start");

            var        screenSystem = Resources.FindObjectsOfTypeAll <ScreenSystem>()[0];
            Vector3    pos          = screenSystem.rightScreen.gameObject.transform.position;
            Quaternion rot          = screenSystem.rightScreen.gameObject.transform.rotation;

            floatingScreenForDiaryButton = FloatingScreen.CreateFloatingScreen(new Vector2(40, 15), false, pos + new Vector3(1.65f, -0.82f, 0f), rot);

            floatingScreenForDiaryButton.SetRootViewController(BeatSaberUI.CreateViewController <DiaryButtonController>(), true);
        }
Esempio n. 14
0
 public static void CreateUI(StatTrakData statTrak)
 {
     if (!Screen)
     {
         SelectedStatTrak = statTrak;
         Screen           = FloatingScreen.CreateFloatingScreen(new Vector2(100, 20), false, new Vector3(1.75f, 0.5f, 1f), Quaternion.Euler(0, 60, 0));
         ViewController   = BeatSaberUI.CreateViewController <StatTrakViewController>();
         Screen.SetRootViewController(ViewController, HMUI.ViewController.AnimationType.None);
     }
     else
     {
         DestroyUI(statTrak);
         CreateUI(statTrak);
     }
 }
Esempio n. 15
0
 public static void DestroyUI(StatTrakData statTrak)
 {
     SelectedStatTrak = null;
     if (Screen != null)
     {
         Screen.gameObject.SetActive(false);
         UnityEngine.Object.Destroy(Screen.gameObject);
         Screen = null;
     }
     if (ViewController != null)
     {
         ViewController.gameObject.SetActive(false);
         UnityEngine.Object.Destroy(ViewController.gameObject);
         ViewController = null;
     }
 }
Esempio n. 16
0
        private void SetupScreens()
        {
            if (this._chatScreen == null)
            {
                var screenSize = new Vector2(this.ChatWidth, this.ChatHeight);
                this._chatScreen = FloatingScreen.CreateFloatingScreen(screenSize, true, this.ChatPosition, Quaternion.identity, 0f, true);
                this._chatScreen.gameObject.layer = 5;
                var rectMask2D = this._chatScreen.GetComponent <RectMask2D>();
                if (rectMask2D)
                {
                    Destroy(rectMask2D);
                }

                this._chatContainer = new GameObject("chatContainer");
                this._chatContainer.transform.SetParent(this._chatScreen.transform, false);
                this._chatContainer.AddComponent <RectMask2D>().rectTransform.sizeDelta = screenSize;

                var canvas = this._chatScreen.GetComponent <Canvas>();
                canvas.worldCamera  = Camera.main;
                canvas.sortingOrder = 3;

                this._chatScreen.SetRootViewController(this, AnimationType.None);
                this._rootGameObject = new GameObject();
                DontDestroyOnLoad(this._rootGameObject);

                this._chatMoverMaterial       = Instantiate(BeatSaberUtils.UINoGlowMaterial);
                this._chatMoverMaterial.color = Color.clear;

                var renderer = this._chatScreen.handle.gameObject.GetComponent <Renderer>();
                renderer.material             = this._chatMoverMaterial;
                renderer.material.mainTexture = this._chatMoverMaterial.mainTexture;

                this._chatScreen.transform.SetParent(this._rootGameObject.transform);
                this._chatScreen.ScreenRotation = Quaternion.Euler(this.ChatRotation);

                this._bg = this._chatScreen.GetComponentsInChildren <ImageView>().FirstOrDefault(x => x.name == "bg");
                this._bg.raycastTarget = false;
                this._bg.material      = Instantiate(this._bg.material);
                this._bg.SetField("_gradient", false);
                this._bg.material.color = Color.white.ColorWithAlpha(1);
                this._bg.color          = this.BackgroundColor;
                this._bg.SetAllDirty();

                this.AddToVRPointer();
                this.UpdateChatUI();
            }
        }
Esempio n. 17
0
 void CreateFlowtingScreens(GameObject obj)
 {
     Logger.Debug("Start create screen");
     try {
         var cameraCube     = obj;
         var cameraPosision = cameraCube.transform.position;
         var cameraRotation = cameraCube.transform.rotation;
         Logger.Debug($"{cameraPosision}");
         var screen   = FloatingScreen.CreateFloatingScreen(new Vector2(80f, 100f), false, new Vector3(cameraPosision.x + 0.9f, cameraPosision.y, cameraPosision.z), new Quaternion(cameraRotation.x, cameraRotation.y - 180f, -cameraRotation.z, cameraRotation.w));
         var mainView = this.factory.Create();
         //mainView.SetCurrentInstance(item.Key, item.Value);
         screen.SetRootViewController(mainView, HMUI.ViewController.AnimationType.None);
         screen.gameObject.transform.SetParent(cameraCube.transform);
         //this.Screens.AddOrUpdate(item.Key, screen, (k, v) => screen);
     }
     catch (Exception e) {
         Logger.Error(e);
     }
 }
Esempio n. 18
0
        private void SetupScreens()
        {
            if (_chatScreen == null)
            {
                var screenSize = new Vector2(ChatWidth, ChatHeight);
                _chatScreen = FloatingScreen.CreateFloatingScreen(screenSize, true, ChatPosition, Quaternion.identity, 0f, true);
                var rectMask2D = _chatScreen.GetComponent <RectMask2D>();
                if (rectMask2D)
                {
                    Destroy(rectMask2D);
                }

                _chatContainer = new GameObject("chatContainer");
                _chatContainer.transform.SetParent(_chatScreen.transform, false);
                _chatContainer.AddComponent <RectMask2D>().rectTransform.sizeDelta = screenSize;

                var canvas = _chatScreen.GetComponent <Canvas>();
                canvas.sortingOrder = 3;

                _chatScreen.SetRootViewController(this, AnimationType.None);
                _rootGameObject = new GameObject();
                DontDestroyOnLoad(_rootGameObject);

                _chatMoverMaterial       = Instantiate(BeatSaberUtils.UINoGlowMaterial);
                _chatMoverMaterial.color = Color.clear;

                var renderer = _chatScreen.handle.gameObject.GetComponent <Renderer>();
                renderer.material             = _chatMoverMaterial;
                renderer.material.mainTexture = _chatMoverMaterial.mainTexture;

                _chatScreen.transform.SetParent(_rootGameObject.transform);
                _chatScreen.ScreenRotation = Quaternion.Euler(ChatRotation);

                _bg                      = _chatScreen.GetComponentInChildren <ImageView>();
                _bg.material             = Instantiate(_bg.material);
                _bg.material.mainTexture = BeatSaberUtils.UINoGlowMaterial.mainTexture;
                _bg.color                = BackgroundColor;

                AddToVRPointer();
                UpdateChatUI();
            }
        }
Esempio n. 19
0
        public static TextMeshProUGUI CreateNotificationText(string text, FloatingScreen screen)
        {
            //var gameObject = new GameObject();
            //GameObject.DontDestroyOnLoad(gameObject);
            //gameObject.transform.position = new Vector3(0, 0f, 2.5f);
            //gameObject.transform.eulerAngles = new Vector3(0, 0, 0);
            //gameObject.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);

            //var canvas = gameObject.AddComponent<Canvas>();
            //canvas.renderMode = RenderMode.WorldSpace;
            //var rectTransform = canvas.transform as RectTransform;
            //rectTransform.sizeDelta = new Vector2(200, 50);

            var notificationText = BeatSaberUI.CreateText(screen.transform as RectTransform, text, new Vector2(0f, 0f), new Vector2(0f, 0f));

            notificationText.text      = text;
            notificationText.fontSize  = 10f;
            notificationText.alignment = TextAlignmentOptions.Center;
            return(notificationText);
        }
Esempio n. 20
0
 private void SetupScreens()
 {
     if (_chatScreen == null)
     {
         _chatScreen = FloatingScreen.CreateFloatingScreen(new Vector2(ChatWidth, ChatHeight), true, ChatPosition, Quaternion.Euler(ChatRotation));
         var canvas = _chatScreen.GetComponent <Canvas>();
         canvas.sortingOrder = 3;
         _chatScreen.SetRootViewController(this, true);
         _rootGameObject = new GameObject();
         DontDestroyOnLoad(_rootGameObject);
         _chatMoverMaterial       = Instantiate(BeatSaberUtils.UINoGlowMaterial);
         _chatMoverMaterial.color = Color.clear;
         var renderer = _chatScreen.handle.gameObject.GetComponent <Renderer>();
         renderer.material = _chatMoverMaterial;
         _chatScreen.transform.SetParent(_rootGameObject.transform);
         _bg          = _chatScreen.gameObject.GetComponent <UnityEngine.UI.Image>();
         _bg.material = Instantiate(BeatSaberUtils.UINoGlowMaterial);
         _bg.color    = BackgroundColor;
         AddToVRPointer();
     }
 }
Esempio n. 21
0
        private static void MenuLoadFresh()
        {
            SaveDataManager.instance.Setup();
            QuestManager.instance.LoadQuests();
            ExperienceSystem.instance.Setup();
            ExperienceSystem.instance.FixOverflowedExperience();
            ExperienceSystem.instance.ApplyExperienceFinished += delegate { SaveDataManager.instance.ApplyToFile(); };

            //ExperienceSystem.instance.Invoke("TestLevel", 5f); //TODO: Remove later, FPFC testing
            var floatingScreen = FloatingScreen.CreateFloatingScreen(new Vector2(120, 52f), true,
                                                                     Float3.ToVector3(config.Value.FSPanelPosition),
                                                                     Quaternion.Euler(Float3.ToVector3(config.Value.FSPanelRotation)));

            floatingScreen.screenMover.OnRelease += (pos, rot) => {
                config.Value.FSPanelPosition = new Float3(pos.x, pos.y, pos.z);
                config.Value.FSPanelRotation = new Float3(rot.eulerAngles.x, rot.eulerAngles.y, rot.eulerAngles.z);
                configProvider.Store(config.Value);
            };
            floatingScreen.SetRootViewController(BeatSaberUI.CreateViewController <OverlayViewController>(), true);
            floatingScreen.GetComponent <Image>().enabled = false;
        }
        protected override void Awake()
        {
            if (_lockSprite == null)
            {
                _lockSprite = BSUIUtilities.LoadSpriteFromResources(LockImageResourcePath);
            }
            if (_unlockSprite == null)
            {
                _unlockSprite = BSUIUtilities.LoadSpriteFromResources(UnlockImageResourcePath);
            }

            _floatingScreen            = FloatingScreen.CreateFloatingScreen(new Vector2(120f, 64f), false, PluginConfig.FloatingSearchKeyboardPosition, PluginConfig.FloatingSearchKeyboardRotation);
            _floatingScreen.HandleSide = FloatingScreen.Side.Top;

            UIUtilities.ParseBSML("EnhancedSearchAndFilters.UI.Views.FloatingKeyboardView.bsml", _floatingScreen.gameObject, this);

            _predictionBar = new GameObject("EnhancedSearchPredictionBar").AddComponent <PredictionBar>();
            _predictionBar.Initialize(_floatingScreen.transform, 3.5f, 15f, -55f, 55f);

            var keyboardGO = new GameObject("EnhancedSearchKeyboard", typeof(FloatingSearchKeyboard), typeof(RectTransform));

            var rt = keyboardGO.GetComponent <RectTransform>();

            rt.SetParent(_floatingScreen.transform, false);
            rt.anchorMin        = Vector2.zero;
            rt.anchorMax        = new Vector2(1f, 0f);
            rt.pivot            = new Vector2(0.5f, 0f);
            rt.anchoredPosition = new Vector2(0f, 2f);
            rt.sizeDelta        = new Vector2(-10f, 40f);

            _keyboard = keyboardGO.GetComponent <FloatingSearchKeyboard>();

            _textDisplayComponent                    = BeatSaberUI.CreateText(_floatingScreen.transform as RectTransform, "", new Vector2(0f, 23.5f), Vector2.zero);
            _textDisplayComponent.fontSize           = 7f;
            _textDisplayComponent.alignment          = TextAlignmentOptions.Center;
            _textDisplayComponent.enableWordWrapping = false;

            base.Awake();
        }
Esempio n. 23
0
        private static IEnumerator ShowFloating(bool isMenu = false)
        {
            yield return(new WaitForEndOfFrame());

            Logger.log.Debug("Showing Floating");
            var is360Level = BS_Utils.Plugin.LevelData?.GameplayCoreSceneSetupData?.difficultyBeatmap?.beatmapData?.spawnRotationEventsCount > 0;
            var pos        = isMenu ? Float3.ToVector3(config.Value.MenuTextStandardLevelPosition): is360Level?Float3.ToVector3(config.Value.HttpText360LevelPosition) : Float3.ToVector3(config.Value.HttpTextStandardLevelPosition);

            var rot = isMenu ? Quaternion.Euler(Float3.ToVector3(config.Value.MenuTextStandardLevelRotation)) : is360Level
                ? Quaternion.Euler(Float3.ToVector3(config.Value.HttpText360LevelRotation))
                : Quaternion.Euler(Float3.ToVector3(config.Value.HttpTextStandardLevelRotation));

            Logger.log.Debug($"is 360 level: {is360Level} | is menu {isMenu}");
            var floatingScreen = FloatingScreen.CreateFloatingScreen(new Vector2(0, 0), false, pos, rot);

            Logger.log.Debug("new floating screen");
            floatingScreen.SetRootViewController(BeatSaberUI.CreateViewController <TextViewController>(), HMUI.ViewController.AnimationType.In);
            Logger.log.Debug("get image component");
            //floatingScreen.GetComponent<Image>().enabled = false;
            Logger.log.Debug("add text creator component");
            floatingScreen.gameObject.AddComponent <TextCreator>();
            Logger.log.Debug("Floating should be shown by now");
        }
Esempio n. 24
0
        public static FloatingScreen CreateScreen(DebugCallbackString[] debugStrings, Vector2?size = null, Vector3?pos = null)
        {
            var screen = FloatingScreen.CreateFloatingScreen(size ?? new Vector2(500, 500), false, pos ?? new Vector3(0, 1, 1), Quaternion.identity);

            var bg = new BackgroundTag().CreateObject(screen.transform);

            bg.GetComponentInChildren <Backgroundable>().ApplyBackground("round-rect-panel");

            var vertical = new VerticalLayoutTag().CreateObject(bg.transform);

            foreach (var debugString in debugStrings)
            {
                var horizontal = new HorizontalLayoutTag().CreateObject(vertical.transform);
                new TextTag().CreateObject(horizontal.transform).GetComponentInChildren <TextMeshProUGUI>().text = debugString.Title;
                var str = new TextTag().CreateObject(horizontal.transform).GetComponentInChildren <TextMeshProUGUI>();
                str.text = debugString.Value;
                debugString.OnValueUpdated += s =>
                {
                    str.text = s;
                };
            }

            return(screen);
        }
Esempio n. 25
0
 public static FloatingScreen CreateScreen(Vector2?size = null, Vector3?pos = null)
 {
     return(FloatingScreen.CreateFloatingScreen(size ?? new Vector2(500, 500), false, pos ?? new Vector3(0, 1, 1), Quaternion.identity));
 }
Esempio n. 26
0
        public void ShowTeamSelection()
        {
            FloatingScreen screen = FloatingScreen.CreateFloatingScreen(new Vector2(100, 50), false, new Vector3(0f, 0.9f, 2.4f), Quaternion.Euler(30f, 0f, 0f));

            screen.SetRootViewController(_teamSelection, false);
        }
        public void Initialize()
        {
            var is360Level = _beatmapData.spawnRotationEventsCount > 0;
            var pos        = is360Level ? _config.Chart360LevelPosition : _config.ChartStandardLevelPosition;
            var rot        = is360Level
                                ? Quaternion.Euler(_config.Chart360LevelRotation)
                                : Quaternion.Euler(_config.ChartStandardLevelRotation);

            _floatingScreen = FloatingScreen.CreateFloatingScreen(_config.ChartSize, false, pos, rot, curvatureRadius: 0f, hasBackground: _config.HasBackground);
            _floatingScreen.SetRootViewController(this, AnimationType.None);
            _floatingScreen.name = nameof(SongChartVisualizer);

            if (_config.HasBackground)
            {
                var imageView = _floatingScreen.GetComponentInChildren <ImageView>();
                imageView.material = _assetLoader.UINoGlowMaterial;
                imageView.color    = _config.CombinedBackgroundColor;

                transform.SetParent(imageView.transform);
            }

            if (_audioTimeSyncController.songLength < 0)
            {
                _shouldNotRunTick = true;
                return;
            }

            // _siraLog.Debug($"There are {_beatmapData.beatmapObjectsData.Count(x => x.beatmapObjectType == BeatmapObjectType.Note)} notes");
            // _siraLog.Debug($"There are {_beatmapData.beatmapLinesData.Count} lines");

            _npsSections = GetNpsSections(_beatmapData);
#if DEBUG
            for (var i = 0; i < _npsSections.Count; i++)
            {
                var npsInfos = _npsSections[i];
                _siraLog.Debug($"Nps at section {i + 1}: {npsInfos.Nps} (from [{npsInfos.FromTime}] to [{npsInfos.ToTime}])");
            }
#endif

            _siraLog.Debug("Loading assetbundle..");
            var assembly = Assembly.GetExecutingAssembly();
            using (var stream = assembly.GetManifestResourceStream("SongChartVisualizer.UI.linegraph"))
            {
                _assetBundle = AssetBundle.LoadFromStream(stream);
            }

            if (!_assetBundle)
            {
                _siraLog.Warn("Failed to load AssetBundle! The chart will not work properly..");
            }
            else
            {
                var prefab = _assetBundle.LoadAsset <GameObject>("LineGraph");
                var sprite = _assetBundle.LoadAsset <Sprite>("Circle");
                var go     = Instantiate(prefab, transform);

                go.transform.Translate(0.04f, 0, 0);
                _windowGraph = go.AddComponent <WindowGraph>();
                _windowGraph.circleSprite          = sprite;
                _windowGraph.transform.localScale /= 10;
                var npsValues = _npsSections.Select(info => info.Nps).ToList();
                _windowGraph.ShowGraph(npsValues, false, linkColor: _config.LineColor);

                _currentSectionIdx = 0;
                _currentSection    = _npsSections[_currentSectionIdx];

                CreateSelfCursor(_config.PointerColor);

                if (_config.PeakWarning)
                {
                    var highestValue = _npsSections.Max(info => info.Nps);
                    _hardestSectionIdx = _npsSections.FindIndex(info => Math.Abs(info.Nps - highestValue) < 0.001f);
                    PrepareWarningText();

                    FadeInTextIfNeeded();
                }
            }
        }
        public BottomScreen()
        {
            _floatingScreen = FloatingScreen.CreateFloatingScreen(new Vector2(DefaultXSize, DefaultYSize), false, new Vector3(1.5f, 0.05f, 1.5f), Quaternion.Euler(50f, 0f, 0f));
            (_floatingScreen.transform as RectTransform).pivot = new Vector2(1f, 0f);

            // this is needed to fix HoverHint position issues that occur because of the change in pivot done to the floating screen
            var wrapperCanvasGO = new GameObject("Wrapper", typeof(RectTransform), typeof(Canvas), typeof(VRGraphicRaycaster), typeof(SetMainCameraToCanvas));
            var rt = wrapperCanvasGO.transform as RectTransform;

            rt.SetParent(_floatingScreen.transform, false);
            rt.anchorMin = Vector2.zero;
            rt.anchorMax = Vector2.one;
            rt.sizeDelta = Vector2.zero;

            var cameraSetter = wrapperCanvasGO.GetComponent <SetMainCameraToCanvas>();

            cameraSetter.SetField("_canvas", wrapperCanvasGO.GetComponent <Canvas>());
            cameraSetter.SetField("_mainCamera", Resources.FindObjectsOfTypeAll <MainCamera>().FirstOrDefault(camera => camera.camera?.stereoTargetEye != StereoTargetEyeMask.None) ?? Resources.FindObjectsOfTypeAll <MainCamera>().FirstOrDefault());

            _outlineImage                = new GameObject("Outline").AddComponent <Image>();
            _outlineImage.color          = OutlineColour;
            _outlineImage.material       = UIUtilities.NoGlowMaterial;
            _outlineImage.type           = Image.Type.Sliced;
            _outlineImage.sprite         = Resources.FindObjectsOfTypeAll <Sprite>().LastOrDefault(x => x.name == "RoundRectSmallStroke");
            _outlineImage.preserveAspect = true;

            _outlineImage.rectTransform.SetParent(wrapperCanvasGO.transform, false);
            _outlineImage.rectTransform.anchorMin = Vector2.zero;
            _outlineImage.rectTransform.anchorMax = Vector2.one;
            _outlineImage.rectTransform.sizeDelta = Vector2.zero;

            var hlg = new GameObject("HorizontalLayoutGroup").AddComponent <HorizontalLayoutGroup>();

            hlg.spacing                = 3.5f;
            hlg.padding                = new RectOffset(2, 2, 1, 1);
            hlg.childAlignment         = TextAnchor.MiddleCenter;
            hlg.childForceExpandWidth  = false;
            hlg.childForceExpandHeight = false;

            rt = hlg.transform as RectTransform;
            rt.SetParent(wrapperCanvasGO.transform, false);
            rt.anchorMin = new Vector2(1f, 0f);
            rt.anchorMax = new Vector2(1f, 0f);
            rt.pivot     = new Vector2(1f, 0f);
            rt.sizeDelta = new Vector2(DefaultXSize, DefaultYSize);

            // icon
            _iconImage                = new GameObject("Icon").AddComponent <Image>();
            _iconImage.material       = UIUtilities.NoGlowMaterial;
            _iconImage.sprite         = BSUIUtilities.LoadSpriteFromResources("EnhancedSearchAndFilters.Assets.bars.png");
            _iconImage.preserveAspect = true;

            var le = _iconImage.gameObject.AddComponent <LayoutElement>();

            le.preferredWidth  = 4.5f;
            le.preferredHeight = 4.5f;

            _iconImage.rectTransform.SetParent(rt, false);

            // text
            _text           = BeatSaberUI.CreateText(rt, "OPTIONS", Vector2.zero, Vector2.zero);
            _text.fontSize  = 4.4f;
            _text.alignment = TextAlignmentOptions.Center;

            // this needs to be the last child, otherwise the outline image will capture all the controller raycasts first
            UIUtilities.ParseBSML("EnhancedSearchAndFilters.UI.Views.BottomScreen.BottomScreenView.bsml", wrapperCanvasGO, this);

            _hoverEventHandler = _floatingScreen.gameObject.AddComponent <EnterExitEventHandler>();
            _hoverEventHandler.PointerEntered += delegate()
            {
                if (_revealAnimation != null)
                {
                    return;
                }
                else if (_contractAnimation != null)
                {
                    UnityCoroutineHelper.Stop(_contractAnimation);
                    _contractAnimation = null;
                }

                _expandAnimation = UnityCoroutineHelper.Start(ExpandAnimationCoroutine());
            };
            _hoverEventHandler.PointerExited += delegate()
            {
                if (_revealAnimation != null)
                {
                    return;
                }

                bool immediate = false;
                if (_expandAnimation != null)
                {
                    UnityCoroutineHelper.Stop(_expandAnimation);
                    _expandAnimation = null;
                    immediate        = true;
                }
                else if (_contractAnimation != null)
                {
                    UnityCoroutineHelper.Stop(_contractAnimation);
                    _contractAnimation = null;
                }

                _contractAnimation = UnityCoroutineHelper.Start(ContractAnimationCoroutine(immediate));
            };

            var sortModeTab = new SortModeTab(_container);

            sortModeTab.SortButtonPressed += () => SortButtonPressed?.Invoke();
            sortModeTab.Visible            = true;

            _currentTab = sortModeTab;
            _tabs[0]    = sortModeTab;
            Logger.log.Notice($"finished constructor, currentTab?={_currentTab == null}");

            HideScreen(true);
        }