Add some more functionality to Freecam

- Option to use Game's camera
- Button to reset position back to original cam pos
- Free cam position will be stored between stopping/starting free cam
This commit is contained in:
Sinai 2022-04-19 19:37:05 +10:00
parent 495bc41a8d
commit 1f87e89b97
2 changed files with 153 additions and 40 deletions

View File

@ -1,6 +1,8 @@
using System; using HarmonyLib;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
@ -21,45 +23,91 @@ namespace UnityExplorer.UI.Panels
public override string Name => "Freecam"; public override string Name => "Freecam";
public override UIManager.Panels PanelType => UIManager.Panels.Freecam; public override UIManager.Panels PanelType => UIManager.Panels.Freecam;
public override int MinWidth => 400; 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 DefaultAnchorMin => new(0.4f, 0.4f);
public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f); public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f);
public override bool NavButtonWanted => true; public override bool NavButtonWanted => true;
public override bool ShouldSaveActiveState => true; public override bool ShouldSaveActiveState => true;
internal static bool inFreeCamMode; internal static bool inFreeCamMode;
internal static bool usingGameCamera;
internal static Camera ourCamera; internal static Camera ourCamera;
internal static Camera lastMainCamera; internal static Camera lastMainCamera;
internal static Vector3 lastCameraMainPos; internal static FreeCamBehaviour freeCamScript;
internal static Quaternion lastCameraMainRot;
internal static float desiredMoveSpeed = 10f; 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 previousMousePosition;
internal static Vector3 lastSetCameraPosition; internal static Vector3 lastSetCameraPosition;
static ButtonRef startStopButton; static ButtonRef startStopButton;
static Toggle useGameCameraToggle;
static InputFieldRef positionInput; static InputFieldRef positionInput;
static InputFieldRef moveSpeedInput; static InputFieldRef moveSpeedInput;
static ButtonRef inspectButton; static ButtonRef inspectButton;
void BeginFreecam() internal static void BeginFreecam()
{ {
inFreeCamMode = true; inFreeCamMode = true;
previousMousePosition = InputManager.MousePosition; previousMousePosition = InputManager.MousePosition;
CacheMainCamera();
SetupFreeCamera();
inspectButton.GameObject.SetActive(true);
}
static void CacheMainCamera()
{
Camera currentMain = Camera.main; Camera currentMain = Camera.main;
if (currentMain) if (currentMain)
{ {
lastMainCamera = currentMain; lastMainCamera = currentMain;
lastCameraMainPos = currentMain.transform.position; originalCameraPosition = currentMain.transform.position;
lastCameraMainRot = currentMain.transform.rotation; originalCameraRotation = currentMain.transform.rotation;
lastMainCamera.enabled = false;
if (currentUserCameraPosition == null)
{
currentUserCameraPosition = currentMain.transform.position;
currentUserCameraRotation = currentMain.transform.rotation;
}
} }
else 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) if (!ourCamera)
{ {
@ -67,44 +115,49 @@ namespace UnityExplorer.UI.Panels
ourCamera.gameObject.tag = "MainCamera"; ourCamera.gameObject.tag = "MainCamera";
GameObject.DontDestroyOnLoad(ourCamera.gameObject); GameObject.DontDestroyOnLoad(ourCamera.gameObject);
ourCamera.gameObject.hideFlags = HideFlags.HideAndDontSave; ourCamera.gameObject.hideFlags = HideFlags.HideAndDontSave;
ourCamera.gameObject.AddComponent<FreeCamBehaviour>();
} }
ourCamera.gameObject.SetActive(true); if (!freeCamScript)
ourCamera.transform.position = lastCameraMainPos; freeCamScript = ourCamera.gameObject.AddComponent<FreeCamBehaviour>();
ourCamera.transform.rotation = lastCameraMainRot;
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; inFreeCamMode = false;
if (usingGameCamera)
{
ourCamera = null;
if (lastMainCamera)
{
lastMainCamera.transform.position = originalCameraPosition;
lastMainCamera.transform.rotation = originalCameraRotation;
}
}
if (ourCamera) if (ourCamera)
ourCamera.gameObject.SetActive(false); ourCamera.gameObject.SetActive(false);
else else
inspectButton.GameObject.SetActive(false); inspectButton.GameObject.SetActive(false);
if (freeCamScript)
{
GameObject.Destroy(freeCamScript);
freeCamScript = null;
}
if (lastMainCamera) if (lastMainCamera)
lastMainCamera.enabled = true; lastMainCamera.enabled = true;
} }
void SetToggleButtonState() static void SetCameraPosition(Vector3 pos)
{
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)
{ {
if (!ourCamera || lastSetCameraPosition == pos) if (!ourCamera || lastSetCameraPosition == pos)
return; return;
@ -122,16 +175,30 @@ namespace UnityExplorer.UI.Panels
positionInput.Text = ParseUtility.ToStringForInput<Vector3>(lastSetCameraPosition); positionInput.Text = ParseUtility.ToStringForInput<Vector3>(lastSetCameraPosition);
} }
// ~~~~~~~~ UI construction / callbacks ~~~~~~~~
protected override void ConstructPanelContent() protected override void ConstructPanelContent()
{ {
startStopButton = UIFactory.CreateButton(ContentRoot, "ToggleButton", "Freecam"); startStopButton = UIFactory.CreateButton(ContentRoot, "ToggleButton", "Freecam");
UIFactory.SetLayoutElement(startStopButton.GameObject, minWidth: 150, minHeight: 25, flexibleWidth: 9999); UIFactory.SetLayoutElement(startStopButton.GameObject, minWidth: 150, minHeight: 25, flexibleWidth: 9999);
startStopButton.OnClick += ToggleButton_OnClick; startStopButton.OnClick += StartStopButton_OnClick;
SetToggleButtonState(); SetToggleButtonState();
AddSpacer(5); 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); AddSpacer(5);
@ -141,11 +208,11 @@ namespace UnityExplorer.UI.Panels
AddSpacer(5); AddSpacer(5);
string instructions = @"Controls: string instructions = @"Controls:
- WASD/Arrows: Movement - WASD / Arrows: Movement
- Space/PgUp: Move up - Space / PgUp: Move up
- LeftControl/PgDown: Move down - LeftCtrl / PgDown: Move down
- Right Mouse Button: Free look - Right Mouse Button: Free look
- Left Shift: Super speed"; - Shift: Super speed";
Text instructionsText = UIFactory.CreateLabel(ContentRoot, "Instructions", instructions, TextAnchor.UpperLeft); Text instructionsText = UIFactory.CreateLabel(ContentRoot, "Instructions", instructions, TextAnchor.UpperLeft);
UIFactory.SetLayoutElement(instructionsText.gameObject, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutElement(instructionsText.gameObject, flexibleWidth: 9999, flexibleHeight: 9999);
@ -180,7 +247,7 @@ namespace UnityExplorer.UI.Panels
return row; return row;
} }
void ToggleButton_OnClick() void StartStopButton_OnClick()
{ {
EventSystemHelper.SetSelectedGameObject(null); EventSystemHelper.SetSelectedGameObject(null);
@ -192,7 +259,44 @@ namespace UnityExplorer.UI.Panels
SetToggleButtonState(); 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); EventSystemHelper.SetSelectedGameObject(null);
@ -206,7 +310,7 @@ namespace UnityExplorer.UI.Panels
SetCameraPosition(parsed); SetCameraPosition(parsed);
} }
private void MoveSpeedInput_OnEndEdit(string input) void MoveSpeedInput_OnEndEdit(string input)
{ {
EventSystemHelper.SetSelectedGameObject(null); EventSystemHelper.SetSelectedGameObject(null);
@ -236,8 +340,17 @@ namespace UnityExplorer.UI.Panels
{ {
if (FreeCamPanel.inFreeCamMode) if (FreeCamPanel.inFreeCamMode)
{ {
if (!FreeCamPanel.ourCamera)
{
FreeCamPanel.EndFreecam();
return;
}
Transform transform = FreeCamPanel.ourCamera.transform; Transform transform = FreeCamPanel.ourCamera.transform;
FreeCamPanel.currentUserCameraPosition = transform.position;
FreeCamPanel.currentUserCameraRotation = transform.rotation;
float moveSpeed = FreeCamPanel.desiredMoveSpeed * Time.deltaTime; float moveSpeed = FreeCamPanel.desiredMoveSpeed * Time.deltaTime;
if (InputManager.GetKey(KeyCode.LeftShift) || InputManager.GetKey(KeyCode.RightShift)) if (InputManager.GetKey(KeyCode.LeftShift) || InputManager.GetKey(KeyCode.RightShift))