From 4c8534b7b36e77a7c7c47a10b163695686391739 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sun, 1 Feb 2026 10:13:56 +0800 Subject: 整合素材 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Mountools/Tools/ToolFreeCamera.cs | 167 +++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100755 Assets/Mountools/Tools/ToolFreeCamera.cs (limited to 'Assets/Mountools/Tools/ToolFreeCamera.cs') 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 _cameraStatus = new(); + + private float _currentSpeed; + private Vector3 _currentRotation; + + // 相机状态 + public bool active => FindObjectOfType() != null; + + public static void FreeCameraEnter() + { + if (! Application.isPlaying) return; + if (FindObjectOfType() != null) return; + + GameObject gameObject = new GameObject("Free Camera"); + Camera selfCamera = gameObject.AddComponent(); + ToolFreeCamera freeCamera = gameObject.AddComponent(); + Camera[] cameras = FindObjectsOfType(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(); + 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 -- cgit