diff options
Diffstat (limited to 'Assets/Mountools/Tools/ToolFreeCamera.cs')
| -rwxr-xr-x | Assets/Mountools/Tools/ToolFreeCamera.cs | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/Assets/Mountools/Tools/ToolFreeCamera.cs b/Assets/Mountools/Tools/ToolFreeCamera.cs new file mode 100755 index 0000000..8f7fce8 --- /dev/null +++ b/Assets/Mountools/Tools/ToolFreeCamera.cs @@ -0,0 +1,167 @@ +#if UNITY_EDITOR
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Mountools.Tools
+{
+ public class ToolFreeCamera : MonoBehaviour
+ {
+ [HideInInspector] public string cameraRotationX = "Mouse Y";
+ [HideInInspector] public string cameraRotationY = "Mouse X";
+ [HideInInspector] public string cameraRotationZ = "Horizontal";
+ [HideInInspector] public string cameraForwardAxisName = "Vertical";
+ [HideInInspector] public string cameraFastMoveButton = "Fire3";
+ [HideInInspector] public string enableRotationZ = "Fire1";
+ [HideInInspector] public string cameraRotationZRecover = "Jump";
+
+ public float cameraSensitivity = 150f;
+ public float cameraMovingSpeed = 20f;
+ public float cameraFastMovingSpeed = 50f;
+ public bool canCameraRotationZ;
+
+ // 场景内相机状态
+ private readonly Dictionary<Camera, bool> _cameraStatus = new();
+
+ private float _currentSpeed;
+ private Vector3 _currentRotation;
+
+ // 相机状态
+ public bool active => FindObjectOfType<ToolFreeCamera>() != null;
+
+ public static void FreeCameraEnter()
+ {
+ if (! Application.isPlaying) return;
+ if (FindObjectOfType<ToolFreeCamera>() != null) return;
+
+ GameObject gameObject = new GameObject("Free Camera");
+ Camera selfCamera = gameObject.AddComponent<Camera>();
+ ToolFreeCamera freeCamera = gameObject.AddComponent<ToolFreeCamera>();
+ Camera[] cameras = FindObjectsOfType<Camera>(true);
+
+ freeCamera._cameraStatus.Clear();
+ foreach (var cam in cameras)
+ {
+ if (cam == selfCamera) continue;
+
+ freeCamera._cameraStatus.Add(cam, cam.gameObject.activeSelf);
+
+ if (cam.gameObject.activeSelf)
+ {
+ var camTransform = cam.transform;
+ var selfCameraTransform = selfCamera.transform;
+
+ selfCameraTransform.position = camTransform.position;
+ freeCamera._currentRotation = camTransform.rotation.eulerAngles;
+
+ selfCamera.fieldOfView = cam.fieldOfView;
+ selfCamera.orthographic = cam.orthographic;
+ selfCamera.depth = cam.depth;
+ selfCamera.aspect = cam.aspect;
+ selfCamera.clearFlags = cam.clearFlags;
+ selfCamera.backgroundColor = cam.backgroundColor;
+
+ cam.gameObject.SetActive(false);
+ continue;
+ }
+
+ cam.gameObject.SetActive(false);
+ }
+
+ Cursor.lockState = CursorLockMode.Locked;
+ Cursor.visible = false;
+ }
+
+ public static void FreeCameraExit()
+ {
+ if (! Application.isPlaying) return;
+ var freeCamera = FindObjectOfType<ToolFreeCamera>();
+ if (freeCamera == null) return;
+
+ freeCamera.gameObject.SetActive(false);
+
+ foreach (var cameras in freeCamera._cameraStatus)
+ {
+ cameras.Key.gameObject.SetActive(cameras.Value);
+ }
+
+ Destroy(freeCamera.gameObject);
+ }
+
+ private void Update()
+ {
+ if (Input.GetKeyDown(KeyCode.Mouse0))
+ {
+ Cursor.lockState = CursorLockMode.Locked;
+ Cursor.visible = false;
+ }
+
+ if (Input.GetKeyDown(KeyCode.Mouse1) || Input.GetKeyDown(KeyCode.Escape))
+ {
+ if (Cursor.lockState == CursorLockMode.None)
+ {
+ FreeCameraExit();
+ }
+ else
+ {
+ Cursor.lockState = CursorLockMode.None;
+ Cursor.visible = true;
+ }
+ }
+
+ UpdateCameraRotation();
+ }
+
+ public void UpdateCameraRotation()
+ {
+ if (Cursor.lockState == CursorLockMode.None) return;
+
+ var camRotationZ = Input.GetAxis(cameraRotationZ);
+
+ var canRotationZ = canCameraRotationZ && Input.GetButton(enableRotationZ);
+
+ // Rotation Control
+ var rotationVector = new Vector3
+ {
+ x = Input.GetAxis(cameraRotationX),
+ y = Input.GetAxis(cameraRotationY),
+ z = canRotationZ ? camRotationZ : 0
+ };
+
+ // Change Rotation
+ var t = transform;
+ _currentRotation.x -= cameraSensitivity * Time.fixedDeltaTime * rotationVector.x;
+ _currentRotation.y += cameraSensitivity * Time.fixedDeltaTime * rotationVector.y;
+ _currentRotation.z -= cameraSensitivity * Time.fixedDeltaTime * rotationVector.z;
+ _currentRotation.x = ClampRotation(_currentRotation.x, -90, 90);
+ _currentRotation.z = ClampRotation(_currentRotation.z, -90, 90);
+
+ if (Input.GetButton(cameraRotationZRecover))
+ _currentRotation.z = Mathf.Lerp(_currentRotation.z, 0, 0.2f);
+
+ t.rotation = Quaternion.Euler(_currentRotation);
+
+ // Movement Control
+ var movementAxisForward = Input.GetAxis(cameraForwardAxisName);
+ var movementAxisRight = canRotationZ ? 0 : camRotationZ;
+
+ var speed = Input.GetButton(cameraFastMoveButton) ? cameraFastMovingSpeed : cameraMovingSpeed;
+ _currentSpeed = Mathf.Lerp(_currentSpeed, speed, 0.3f);
+
+ t.position += t.forward * (Time.deltaTime * _currentSpeed * movementAxisForward) +
+ t.right * (Time.deltaTime * _currentSpeed * movementAxisRight);
+ }
+
+ private static float ClampRotation(float n, float min, float max)
+ {
+ if (n < -360)
+ n += 360;
+
+ if (n > 360)
+ n-= 360;
+
+ return Mathf.Clamp(n, min, max);
+ }
+ }
+}
+
+#endif
\ No newline at end of file |
