diff --git a/UnityEditorPackage/Runtime/UnityExplorer.STANDALONE.Mono.dll b/UnityEditorPackage/Runtime/UnityExplorer.STANDALONE.Mono.dll index 4cdc1e1..2787e92 100644 Binary files a/UnityEditorPackage/Runtime/UnityExplorer.STANDALONE.Mono.dll and b/UnityEditorPackage/Runtime/UnityExplorer.STANDALONE.Mono.dll differ diff --git a/src/UI/Panels/FreeCamPanel.cs b/src/UI/Panels/FreeCamPanel.cs index d5c0b20..b7b091c 100644 --- a/src/UI/Panels/FreeCamPanel.cs +++ b/src/UI/Panels/FreeCamPanel.cs @@ -1,6 +1,8 @@ -using System; +using HarmonyLib; +using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using UnityEngine; using UnityEngine.EventSystems; @@ -21,45 +23,91 @@ namespace UnityExplorer.UI.Panels public override string Name => "Freecam"; public override UIManager.Panels PanelType => UIManager.Panels.Freecam; - public override int MinWidth => 400; - public override int MinHeight => 300; + public override int MinHeight => 320; public override Vector2 DefaultAnchorMin => new(0.4f, 0.4f); public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f); public override bool NavButtonWanted => true; public override bool ShouldSaveActiveState => true; internal static bool inFreeCamMode; + internal static bool usingGameCamera; internal static Camera ourCamera; internal static Camera lastMainCamera; - internal static Vector3 lastCameraMainPos; - internal static Quaternion lastCameraMainRot; + internal static FreeCamBehaviour freeCamScript; internal static float desiredMoveSpeed = 10f; + + internal static Vector3 originalCameraPosition; + internal static Quaternion originalCameraRotation; + + internal static Vector3? currentUserCameraPosition; + internal static Quaternion? currentUserCameraRotation; + internal static Vector3 previousMousePosition; + internal static Vector3 lastSetCameraPosition; static ButtonRef startStopButton; + static Toggle useGameCameraToggle; static InputFieldRef positionInput; static InputFieldRef moveSpeedInput; static ButtonRef inspectButton; - void BeginFreecam() + internal static void BeginFreecam() { inFreeCamMode = true; previousMousePosition = InputManager.MousePosition; + CacheMainCamera(); + SetupFreeCamera(); + + inspectButton.GameObject.SetActive(true); + } + + static void CacheMainCamera() + { Camera currentMain = Camera.main; if (currentMain) { lastMainCamera = currentMain; - lastCameraMainPos = currentMain.transform.position; - lastCameraMainRot = currentMain.transform.rotation; - lastMainCamera.enabled = false; + originalCameraPosition = currentMain.transform.position; + originalCameraRotation = currentMain.transform.rotation; + + if (currentUserCameraPosition == null) + { + currentUserCameraPosition = currentMain.transform.position; + currentUserCameraRotation = currentMain.transform.rotation; + } } else - lastCameraMainRot = Quaternion.identity; + originalCameraRotation = Quaternion.identity; + } + + static void SetupFreeCamera() + { + if (useGameCameraToggle.isOn) + { + if (!lastMainCamera) + { + ExplorerCore.LogWarning($"There is no previous Camera found, reverting to default Free Cam."); + useGameCameraToggle.isOn = false; + } + else + { + usingGameCamera = true; + ourCamera = lastMainCamera; + } + } + + if (!useGameCameraToggle.isOn) + { + usingGameCamera = false; + + if (lastMainCamera) + lastMainCamera.enabled = false; + } if (!ourCamera) { @@ -67,44 +115,49 @@ namespace UnityExplorer.UI.Panels ourCamera.gameObject.tag = "MainCamera"; GameObject.DontDestroyOnLoad(ourCamera.gameObject); ourCamera.gameObject.hideFlags = HideFlags.HideAndDontSave; - ourCamera.gameObject.AddComponent(); } - ourCamera.gameObject.SetActive(true); - ourCamera.transform.position = lastCameraMainPos; - ourCamera.transform.rotation = lastCameraMainRot; + if (!freeCamScript) + freeCamScript = ourCamera.gameObject.AddComponent(); - inspectButton.GameObject.SetActive(true); + ourCamera.transform.position = (Vector3)currentUserCameraPosition; + ourCamera.transform.rotation = (Quaternion)currentUserCameraRotation; + + ourCamera.gameObject.SetActive(true); + ourCamera.enabled = true; } - void EndFreecam() + internal static void EndFreecam() { inFreeCamMode = false; + if (usingGameCamera) + { + ourCamera = null; + + if (lastMainCamera) + { + lastMainCamera.transform.position = originalCameraPosition; + lastMainCamera.transform.rotation = originalCameraRotation; + } + } + if (ourCamera) ourCamera.gameObject.SetActive(false); else inspectButton.GameObject.SetActive(false); + if (freeCamScript) + { + GameObject.Destroy(freeCamScript); + freeCamScript = null; + } + if (lastMainCamera) lastMainCamera.enabled = true; } - void SetToggleButtonState() - { - if (inFreeCamMode) - { - RuntimeHelper.SetColorBlockAuto(startStopButton.Component, new(0.4f, 0.2f, 0.2f)); - startStopButton.ButtonText.text = "End Freecam"; - } - else - { - RuntimeHelper.SetColorBlockAuto(startStopButton.Component, new(0.2f, 0.4f, 0.2f)); - startStopButton.ButtonText.text = "Begin Freecam"; - } - } - - void SetCameraPosition(Vector3 pos) + static void SetCameraPosition(Vector3 pos) { if (!ourCamera || lastSetCameraPosition == pos) return; @@ -122,16 +175,30 @@ namespace UnityExplorer.UI.Panels positionInput.Text = ParseUtility.ToStringForInput(lastSetCameraPosition); } + // ~~~~~~~~ UI construction / callbacks ~~~~~~~~ + protected override void ConstructPanelContent() { startStopButton = UIFactory.CreateButton(ContentRoot, "ToggleButton", "Freecam"); UIFactory.SetLayoutElement(startStopButton.GameObject, minWidth: 150, minHeight: 25, flexibleWidth: 9999); - startStopButton.OnClick += ToggleButton_OnClick; + startStopButton.OnClick += StartStopButton_OnClick; SetToggleButtonState(); AddSpacer(5); - AddInputField("Position", "Camera Pos:", "eg. 0 0 0", out positionInput, PositionInput_OnEndEdit); + GameObject toggleObj = UIFactory.CreateToggle(ContentRoot, "UseGameCameraToggle", out useGameCameraToggle, out Text toggleText); + UIFactory.SetLayoutElement(toggleObj, minHeight: 25, flexibleWidth: 9999); + useGameCameraToggle.onValueChanged.AddListener(OnUseGameCameraToggled); + useGameCameraToggle.isOn = false; + toggleText.text = "Use Game Camera?"; + + AddSpacer(5); + + GameObject posRow = AddInputField("Position", "Freecam Pos:", "eg. 0 0 0", out positionInput, PositionInput_OnEndEdit); + + ButtonRef resetPosButton = UIFactory.CreateButton(posRow, "ResetButton", "Reset"); + UIFactory.SetLayoutElement(resetPosButton.GameObject, minWidth: 70, minHeight: 25); + resetPosButton.OnClick += OnResetPosButtonClicked; AddSpacer(5); @@ -141,11 +208,11 @@ namespace UnityExplorer.UI.Panels AddSpacer(5); string instructions = @"Controls: -- WASD/Arrows: Movement -- Space/PgUp: Move up -- LeftControl/PgDown: Move down +- WASD / Arrows: Movement +- Space / PgUp: Move up +- LeftCtrl / PgDown: Move down - Right Mouse Button: Free look -- Left Shift: Super speed"; +- Shift: Super speed"; Text instructionsText = UIFactory.CreateLabel(ContentRoot, "Instructions", instructions, TextAnchor.UpperLeft); UIFactory.SetLayoutElement(instructionsText.gameObject, flexibleWidth: 9999, flexibleHeight: 9999); @@ -180,7 +247,7 @@ namespace UnityExplorer.UI.Panels return row; } - void ToggleButton_OnClick() + void StartStopButton_OnClick() { EventSystemHelper.SetSelectedGameObject(null); @@ -192,7 +259,44 @@ namespace UnityExplorer.UI.Panels SetToggleButtonState(); } - private void PositionInput_OnEndEdit(string input) + void SetToggleButtonState() + { + if (inFreeCamMode) + { + RuntimeHelper.SetColorBlockAuto(startStopButton.Component, new(0.4f, 0.2f, 0.2f)); + startStopButton.ButtonText.text = "End Freecam"; + } + else + { + RuntimeHelper.SetColorBlockAuto(startStopButton.Component, new(0.2f, 0.4f, 0.2f)); + startStopButton.ButtonText.text = "Begin Freecam"; + } + } + + void OnUseGameCameraToggled(bool value) + { + EventSystemHelper.SetSelectedGameObject(null); + + if (!inFreeCamMode) + return; + + EndFreecam(); + BeginFreecam(); + } + + void OnResetPosButtonClicked() + { + currentUserCameraPosition = originalCameraPosition; + currentUserCameraRotation = originalCameraRotation; + + if (inFreeCamMode && ourCamera) + { + ourCamera.transform.position = (Vector3)currentUserCameraPosition; + ourCamera.transform.rotation = (Quaternion)currentUserCameraRotation; + } + } + + void PositionInput_OnEndEdit(string input) { EventSystemHelper.SetSelectedGameObject(null); @@ -206,7 +310,7 @@ namespace UnityExplorer.UI.Panels SetCameraPosition(parsed); } - private void MoveSpeedInput_OnEndEdit(string input) + void MoveSpeedInput_OnEndEdit(string input) { EventSystemHelper.SetSelectedGameObject(null); @@ -236,8 +340,17 @@ namespace UnityExplorer.UI.Panels { if (FreeCamPanel.inFreeCamMode) { + if (!FreeCamPanel.ourCamera) + { + FreeCamPanel.EndFreecam(); + return; + } + Transform transform = FreeCamPanel.ourCamera.transform; + FreeCamPanel.currentUserCameraPosition = transform.position; + FreeCamPanel.currentUserCameraRotation = transform.rotation; + float moveSpeed = FreeCamPanel.desiredMoveSpeed * Time.deltaTime; if (InputManager.GetKey(KeyCode.LeftShift) || InputManager.GetKey(KeyCode.RightShift))