Tz2/Assets/Framework/Scripts/Runtime/Engine/Engine.Camera/CameraControl/CameraControlComponent.cs

236 lines
9.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DG.Tweening;
using UnityEngine;
using NaughtyAttributes;
using UnityEngine.EventSystems;
namespace Framework.Scripts.Runtime.Engine.Engine.Camera.CameraControl
{
public class CameraControlComponent : ICameraController
{
public enum CameraEnum
{
TopView,
FrontView
}
//相机跟随的目标物体,一般是一个空物体
[SerializeField] private GameObject target;
[HorizontalLine(color: EColor.Blue)] [SerializeField] [Label("启用旋转")]
private bool enableMouseFunctions = true;
[SerializeField] [Label("启用鼠标碰到UI禁用脚本")]
private bool enableMouseOverUI = true;
[SerializeField] private CameraEnum cameraEnum;
private float middleSpeed = 2;
private int MouseWheelSensitivity = 1; //滚轮灵敏度设置
private int MouseZoomMin = 10; //相机距离最小值
private int MouseZoomMax = 9999; //相机距离最大值
private float xSpeed = 250.0f; //旋转视角时相机x轴转速
private float ySpeed = 120.0f; //旋转视角时相机y轴转速
private float Distance = 20; //相机和target之间的距离因为相机的Z轴总是指向target也就是相机z轴方向上的距离
//[BoxGroup("参数")][SerializeField][Label("角度最小限制")] private int yMinLimit = -360;
//[BoxGroup("参数")][SerializeField][Label("角度最大限制")] private int yMaxLimit = 360;
private Vector2 minMaxSlider;
private float x = 0.0f; //存储相机的euler角
private float y = 0.0f; //存储相机的euler角
private Vector3 targetOnScreenPosition; //目标的屏幕坐标第三个值为z轴距离
private Quaternion storeRotation; //存储相机的姿态四元数
private Vector3 CameraTargetPosition; //target的位置
private Vector3 initPosition; //平移时用于存储平移的起点位置
private Vector3 cameraX; //相机的x轴方向向量
private Vector3 cameraY; //相机的y轴方向向量
private Vector3 cameraZ; //相机的z轴方向向量
private Vector3 initScreenPos; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
private Vector3 curScreenPos; //当前鼠标的屏幕坐标(第三个值其实没什么用)
private Vector2 jilu;
private Transform cameraTransform;
public void Init(Transform cam, Transform target)
{
cameraTransform = cam;
this.target = target.gameObject;
cameraEnum = CameraEnum.FrontView;
Vector3 angles = cameraTransform.eulerAngles;
x = angles.y;
y = angles.x;
CameraTargetPosition = target.transform.position;
Distance = Vector3.Distance(cameraTransform.position, target.transform.position);
// 给摄像机一个初始的位置和角度
SetCameraPositionAndRotation();
}
public void MoveTargetTo(Vector3 newPosition, float newfloat)
{
target.transform.DOMove(newPosition, 2).OnUpdate(() =>
{
Vector3 mPosition = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + target.transform.position;
cameraTransform.position = mPosition;
CameraTargetPosition = target.transform.position;
}
);
}
void SetCameraPositionAndRotation()
{
//Vector3 position = rotation * new Vector3(0.0f, 0.0f, -11) + target.transform.position;
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, minMaxSlider.x, minMaxSlider.y);
storeRotation = Quaternion.Euler(y, x, 0);
var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
cameraTransform.rotation = storeRotation;
cameraTransform.position = position;
}
//将angle限制在min~max之间
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
public GameObject GetTarget()
{
return target;
}
public void UpdateValue(Vector2 minMax)
{
minMaxSlider = minMax;
}
public void ControlCamera()
{
if (enableMouseOverUI)
{
if (EventSystem.current.IsPointerOverGameObject())
{
return;
}
}
if (enableMouseFunctions)
{
//鼠标右键旋转功能
if (Input.GetMouseButton(1))
{
//如果是顶视图,只能左右旋转,不能上下
if (cameraEnum == CameraEnum.FrontView)
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, minMaxSlider.x, minMaxSlider.y);
storeRotation = Quaternion.Euler(y, x, 0);
var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
Debug.Log(storeRotation);
cameraTransform.rotation = storeRotation;
cameraTransform.position = position;
}
else
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
//y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
//y = ClampAngle(y, minMaxSlider.x, minMaxSlider.y);
storeRotation = Quaternion.Euler(90, x, 0);
var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;
cameraTransform.rotation = storeRotation;
cameraTransform.position = position;
}
}
else if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
{
if (Distance >= MouseZoomMin && Distance <= MouseZoomMax)
{
Distance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
}
if (Distance < MouseZoomMin)
{
Distance = MouseZoomMin;
}
if (Distance > MouseZoomMax)
{
Distance = MouseZoomMax;
}
cameraTransform.position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition;
}
//鼠标中键平移
if (Input.GetMouseButtonDown(2))
{
cameraX = cameraTransform.right;
cameraY = cameraTransform.up;
cameraZ = cameraTransform.forward;
initScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
Debug.Log("downOnce");
//targetOnScreenPosition.z为目标物体到相机xmidbuttonDownPositiony平面的法线距离
if (UnityEngine.Camera.main != null) targetOnScreenPosition = UnityEngine.Camera.main.WorldToScreenPoint(CameraTargetPosition);
initPosition = CameraTargetPosition;
}
if (Input.GetMouseButton(2))
{
curScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
//0.01这个系数是控制平移的速度要根据相机和目标物体的distance来灵活选择
Vector3 vv = initPosition - (0.01f * middleSpeed) * ((curScreenPos.x - initScreenPos.x) * cameraX +
(curScreenPos.y - initScreenPos.y) * cameraY);
target.transform.position = new Vector3(vv.x, vv.y, vv.z);
//重新计算位置
Vector3 mPosition = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + target.transform.position;
cameraTransform.position = mPosition;
// //用这个会让相机的平移变得更平滑但是可能在你buttonup时未使相机移动到应到的位置导致再进行旋转与缩放操作时出现短暂抖动
//transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
}
if (Input.GetMouseButtonUp(2))
{
Debug.Log("upOnce");
//平移结束把cameraTargetPosition的位置更新一下不然会影响缩放与旋转功能
CameraTargetPosition = target.transform.position;
}
}
}
}
}