using UnityEngine; namespace DebuggingEssentials { [DefaultExecutionOrder(99000000)] public class NavigationCamera : MonoBehaviour { public static NavigationCamera instance; public static float fov; public static bool followTarget; public static Camera cam; public SO_NavigationCamera data; private Transform t; private GameObject go; private Vector3 currentSpeed; private Vector3 position; private Vector3 startPosition; private Vector3 navPosition; private Vector3 followPosition; private Quaternion rotation; private Quaternion startRotation; private Quaternion navRotation; private Quaternion followRotation; private Vector2 deltaMouse; private Vector2 mousePosOld; private float tStamp; private float deltaTime; private float oldFov; private float scrollWheel; private GameObject selectionIndicatorGO; private Transform selectionIndicatorT; public static void ResetStatic() { followTarget = false; } private void Awake() { instance = this; go = base.gameObject; t = base.transform; cam = GetComponent(); tStamp = Time.realtimeSinceStartup; startPosition = (navPosition = t.position); startRotation = (navRotation = t.rotation); navRotation = ResetRotZ(navRotation, roundTo180: false); fov = (oldFov = cam.fieldOfView); selectionIndicatorGO = RuntimeInspector.selectionIndicatorGO; selectionIndicatorT = selectionIndicatorGO.transform; if (followTarget) { ResetFollowPosRot(); } } private void OnDestroy() { if (instance == this) { instance = null; } RestoreCam(); } private void Update() { if (RuntimeInspector.instance == null) { Object.Destroy(this); return; } if (EventInput.isKeyDownFollowCamera) { followTarget = !followTarget; if (followTarget) { ResetFollowPosRot(); } } if (WindowManager.eventHandling.hasEntered) { scrollWheel = 0f; } else { scrollWheel = (0f - EventInput.mouseScrollDelta) * data.mouseScrollWheelMulti.value; } } private Quaternion ResetRotZ(Quaternion rot, bool roundTo180 = true) { Vector3 eulerAngles = rot.eulerAngles; if (roundTo180) { eulerAngles.z = Mathf.Round(eulerAngles.z / 180f) * 180f; } else { eulerAngles.z = 0f; } return Quaternion.Euler(eulerAngles); } private void LateUpdate() { if (RuntimeInspector.instance == null) { Object.Destroy(this); return; } deltaMouse = EventInput.mousePos - mousePosOld; mousePosOld = EventInput.mousePos; float speedMulti = GetSpeedMulti(); cam.fieldOfView = fov; deltaTime = Time.realtimeSinceStartup - tStamp; tStamp = Time.realtimeSinceStartup; Vector3 zero = Vector3.zero; if (followTarget) { RuntimeInspector.UpdateSelectedIndicatorTransform(); FollowTarget(); } if (EventInput.isMouseButtonDown1) { Quaternion quaternion = t.rotation; if (followTarget) { t.rotation = rotation; } else { t.rotation = navRotation; } t.Rotate(0f, deltaMouse.x * data.mouseSensitity.value * 0.125f, 0f, Space.World); t.Rotate(deltaMouse.y * data.mouseSensitity.value * 0.125f, 0f, 0f, Space.Self); if (followTarget) { followRotation = Quaternion.Inverse(ResetRotZ(selectionIndicatorT.rotation, roundTo180: false)) * ResetRotZ(t.rotation); } else { navRotation = ResetRotZ(t.rotation); } t.rotation = quaternion; if (EventInput.isKeyW) { zero.z = 1f; } else if (EventInput.isKeyS) { zero.z = -1f; } if (EventInput.isKeyD) { zero.x = 1f; } else if (EventInput.isKeyA) { zero.x = -1f; } if (EventInput.isKeyE) { zero.y = 1f; } else if (EventInput.isKeyQ) { zero.y = -1f; } zero *= speedMulti; } if (EventInput.isMouseButtonDown2) { zero.x = (0f - deltaMouse.x / deltaTime) / 60f; zero.y = deltaMouse.y / deltaTime / 60f; zero *= speedMulti * data.mouseStrafeMulti.value * 0.1f; currentSpeed = zero; } else { Lerp2Way(ref currentSpeed, zero, data.accelMulti.value, data.decelMulti.value); } if (RuntimeInspector.selectionIndicatorGO.activeInHierarchy && EventInput.isFocusCameraKey && !EventInput.isAlignWithViewKey && !EventInput.isMoveToViewKey) { ResetFollowPosRot(); FollowTarget(); } if (!followTarget) { t.rotation = (rotation = navRotation); navPosition += t.TransformDirection(currentSpeed * deltaTime) + t.forward * scrollWheel * GetSpeedMultiScrollWheel() * deltaTime; t.position = (position = navPosition); } if (RuntimeInspector.selectedGO != null && EventInput.isFocusCameraKey) { if (EventInput.isAlignWithViewKey) { RuntimeInspector.selectedGO.transform.position = t.position; RuntimeInspector.selectedGO.transform.forward = t.forward; } else if (EventInput.isMoveToViewKey) { RuntimeInspector.selectedGO.transform.position = t.position + t.forward * 2f; } } } private void FollowTarget() { if (RuntimeInspector.selectedGO == go || RuntimeInspector.selectedGO == RuntimeInspector.selectionIndicatorGO) { followTarget = false; return; } t.rotation = (rotation = (navRotation = ResetRotZ(selectionIndicatorT.rotation, roundTo180: false) * followRotation)); followPosition += selectionIndicatorT.InverseTransformDirection(t.TransformDirection(currentSpeed * deltaTime) + t.forward * scrollWheel * deltaTime); t.position = (position = (navPosition = selectionIndicatorT.position + selectionIndicatorT.rotation * followPosition)); } public void ResetFollowPosRot() { Transform transform = RuntimeInspector.selectionIndicatorGO.transform; t.rotation = transform.rotation; t.position = transform.position; followPosition = new Vector3(0f, 0f, -2f); followRotation = Quaternion.identity; } public void SetCam() { t.rotation = rotation; t.position = position; } public void RestoreCam() { t.position = startPosition; t.rotation = startRotation; cam.fieldOfView = oldFov; } private float GetSpeedMulti() { if (EventInput.isShiftKey) { return data.speedFast.value; } if (EventInput.isControlKey) { return data.speedSlow.value; } return data.speedNormal.value; } private float GetSpeedMultiScrollWheel() { if (EventInput.isShiftKey) { return 2f; } if (EventInput.isControlKey) { return 0.5f; } return 1f; } private void Lerp2Way(ref Vector3 v, Vector3 targetV, float upMulti, float downMulti) { Lerp2Way(ref v.x, targetV.x, upMulti, downMulti); Lerp2Way(ref v.y, targetV.y, upMulti, downMulti); Lerp2Way(ref v.z, targetV.z, upMulti, downMulti); } private void Lerp2Way(ref float v, float targetV, float upMulti, float downMulti) { v = Mathf.Lerp(t: ((!(Mathf.Abs(v) < Mathf.Abs(targetV))) ? downMulti : upMulti) * deltaTime, a: v, b: targetV); } } }