LMQT/Assets/Scripts/CameraControlSystem.cs
2024-12-10 09:03:45 +08:00

249 lines
8.1 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Cinemachine;
using Unity.VisualScripting;
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine.UIElements;
namespace CodeMonkey.CameraSystem {
public class CameraControlSystem : MonoBehaviour {
[SerializeField] private CinemachineVirtualCamera cinemachineVirtualCamera;
[SerializeField] private bool useDragPan = true;
[SerializeField] private bool LowerY
= true;
[SerializeField] private bool MoveForward = false;
[SerializeField] private float dragPanSpeed = 1f;
[SerializeField] private float RotateSpeed = 50f;
[SerializeField] private float zoomSpeed = 10f;
[SerializeField] private float rotateMin = -30f;
[SerializeField] private float rotateMax = 60f;
[SerializeField] private float QESpeed = 60f;
[SerializeField] private float followOffsetMin = 5f;
[SerializeField] private float followOffsetMax = 50f;
[SerializeField] private float followOffsetMinY = 10f;
[SerializeField] private float followOffsetMaxY = 50f;
private bool originalAOn = false;
private bool originalBOn = false;
private bool dragPanMoveActive;
private Vector2 lastMousePosition;
private bool RotateActive;
private Vector3 followOffset;
public bool OnUI = false;
private float currentRotation = 0f;//µ±Ç°Ðýת½Ç¶È
private void Awake()
{
followOffset = cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset;
}
private void Update() {
if (useDragPan) {
HandleCameraMovementDragPan();
originalAOn = true;
}
HandleCameraRotation();
HandleCameraMouseRotation();
if (LowerY)
{
HandleCameraZoom_LowerY();
originalBOn = true;
}
if (MoveForward)
{
HandleCameraZoom_MoveForward();
}
if (EventSystem.current.IsPointerOverGameObject())
{
OnUI = true;
}
else
{
OnUI = false;
}
if (OnUI == true)
{
useDragPan = false;
LowerY = false;
}
else
{
if (originalAOn)
{
useDragPan = true;
}
else
{
useDragPan = false;
}
if (originalBOn)
{
LowerY = true;
}
else
{
LowerY = false;
}
}
//Debug.Log(followOffset);
}
private void HandleCameraMovementDragPan() {
Vector3 inputDir = new Vector3(0, 0, 0);
if (Input.GetMouseButtonDown(0)) {
dragPanMoveActive = true;
lastMousePosition = Input.mousePosition;
}
if (Input.GetMouseButtonUp(0)) {
dragPanMoveActive = false;
}
if (dragPanMoveActive) {
Vector2 mouseMovementDelta = (Vector2)Input.mousePosition - lastMousePosition;
// float dragPanSpeed = 1f;
inputDir.x = mouseMovementDelta.x * dragPanSpeed;
inputDir.z = mouseMovementDelta.y * dragPanSpeed;
lastMousePosition = Input.mousePosition;
}
Vector3 moveDir = transform.forward * inputDir.z + transform.right * inputDir.x;
float moveSpeed = 1f;
transform.position += moveDir * moveSpeed * Time.deltaTime;
transform.position = new Vector3(Mathf.Clamp(transform.position.x, -.3f, .7f), 0, Mathf.Clamp(transform.position.z, -1.66f, 1.44f));
}
private void HandleCameraRotation() {
float rotateDir = 0f;
if (Input.GetKey(KeyCode.Q)) rotateDir = +1f;
if (Input.GetKey(KeyCode.E)) rotateDir = -1f;
transform.eulerAngles += new Vector3(0, rotateDir * RotateSpeed * Time.deltaTime, 0);
transform.eulerAngles = new Vector3(0, ClampAngle(transform.eulerAngles.y, rotateMin, rotateMax), 0);
//Debug.Log(transform.eulerAngles);
}
private void HandleCameraMouseRotation()
{
float rotateDir = 0f;
if (Input.GetMouseButtonDown(1))
{
RotateActive = true;
lastMousePosition = Input.mousePosition;
}
if (Input.GetMouseButtonUp(1))
{
RotateActive = false;
}
if (RotateActive)
{
float mouseMovementDelta=Input.mousePosition .x-lastMousePosition.x;
float RotateSpeed = 2f;
rotateDir = mouseMovementDelta * RotateSpeed;
}
float rotateSpeed = .1f;
transform.eulerAngles += new Vector3(0, rotateDir * rotateSpeed * Time.deltaTime, 0);
}
private void HandleCameraZoom_MoveForward()
{
Vector3 zoomDir = followOffset.normalized;
float zoomAmount = 3f;
if (Input.mouseScrollDelta.y > 0)
{
followOffset -= zoomDir * zoomAmount;
}
if (Input.mouseScrollDelta.y < 0)
{
followOffset += zoomDir * zoomAmount;
}
if (followOffset.magnitude < followOffsetMin)
{
followOffset = zoomDir * followOffsetMin;
}
if (followOffset.magnitude > followOffsetMax)
{
followOffset = zoomDir * followOffsetMax;
}
cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset =
Vector3.Lerp(cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset, followOffset, Time.deltaTime * zoomSpeed);
}
private void HandleCameraZoom_LowerY()
{
float zoomAmount = .3f;
if (Input.mouseScrollDelta.y > 0)
{
followOffset.y -= zoomAmount;
}
if (Input.mouseScrollDelta.y < 0)
{
followOffset.y += zoomAmount;
}
followOffset.y = Mathf.Clamp(followOffset.y, followOffsetMinY, followOffsetMaxY);
cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset =
Vector3.Lerp(cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset, followOffset, Time.deltaTime * zoomSpeed);
}
public void zhuanQ()
{
if (currentRotation < rotateMax)
{
transform.DORotate(new Vector3(0, QESpeed, 0), 1f, RotateMode.LocalAxisAdd);
//transform.rotation = Quaternion.Euler(0, QESpeed, 0);
currentRotation += QESpeed;
}
}
public void zhuanE()
{
if (currentRotation > rotateMin)
{
transform.DORotate(new Vector3(0, -QESpeed, 0), 1f, RotateMode.LocalAxisAdd);
currentRotation -= QESpeed;
}
}
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 0;
if (angle > 180)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
public void resetView()
{
followOffset = new Vector3(0, 2, 2);
Vector3 move = new Vector3(0.25f, 0, 0.2f);
cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset = followOffset;
transform.DOMove(move, 1f);
transform.DORotate(new Vector3(0,0,0) , .5f);
currentRotation = 0;
}
}
}