Files
2026-03-04 09:37:33 +08:00

304 lines
6.9 KiB
C#

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<Camera>();
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);
}
}
}