GQ_Communicate/GQ_TongXin/Assets/Scripts/Camera/CameraRT.cs

272 lines
7.1 KiB
C#

using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// 相机控制
/// </summary>
public class CameraRT : MonoBehaviour
{
public Camera cam;
[Header("目标物体")]
Transform target;
[Header("旋转角度")]
public float x = 0f;
public float y = 0f;
public float z = 0f;
[Header("移动、旋转、缩放速度值")]
public float xSpeed_move = 600;
public float ySpeed_move = 600;
public float xSpeed_rotate = 2;
public float ySpeed_rotate = 2;
public float mSpeed_scale = 150;
[Header("y轴角度限制")]
public float yMinLimit = 2;
public float yMaxLimit = 90;
[Header("x轴角度限制")]
public float leftMax = -365;
public float rightMax = 365;
[Header("距离限制")]
public float distance = 400;
public float minDistance = 10f;
public float maxDistance = 400f;
[Header("阻尼设置")]
public bool needDamping = true;
public float damping = 6f;
[Header("相机活动范围")]
public bool isRangeClamped;
public float xMinValue = -100f;
public float xMaxValue = 100f;
public float zMinValue = -100f;
public float zMaxValue = 100f;
[Header("自动旋转")]
public bool autoRotate;
public float rotateTimer = 15;
public float rotateSpeed = 5;
float rotateTimer_temp;
bool isAutoRotating = false;
//动态调节相机缩放的灵敏度
float tempSpeed;
private void Start()
{
if (cam == null)
{
cam = Camera.main;
}
target = transform.GetChild(0);
target.gameObject.AddComponent<CameraTargetFollowCam>();
x = cam.transform.localEulerAngles.y;
y = cam.transform.localEulerAngles.x;
tempSpeed = xSpeed_move;
rotateTimer_temp = rotateTimer;
}
public void SetTarget(Transform _target)
{
target.position = _target.position;
distance = _target.localScale.x;
y = _target.eulerAngles.x;
x = _target.eulerAngles.y;
}
public void SetTarget(Transform _target, float _distance)
{
target.position = _target.position;
distance = _distance;
y = _target.eulerAngles.x;
x = _target.eulerAngles.y;
}
public void SetTarget(Vector3 _target, float _distance)
{
target.position = _target;
distance = _distance;
//y = _target.eulerAngles.x;
//x = _target.eulerAngles.y;
}
Vector3 oldMousePos;
void Update()
{
if (!autoRotate)
return;
if (oldMousePos != Input.mousePosition || Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2))
{
rotateTimer = rotateTimer_temp;
if (isAutoRotating)
{
x = cam.transform.eulerAngles.y;
y = cam.transform.eulerAngles.x;
}
}
oldMousePos = Input.mousePosition;
if (rotateTimer <= 0)
{
isAutoRotating = true;
//cam.transform.LookAt(target);
//cam.transform.RotateAround(target.position, Vector3.up, -Time.deltaTime * rotateSpeed);
rotateTimer = rotateTimer_temp;
}
else
{
rotateTimer -= Time.deltaTime;
isAutoRotating = false;
}
}
void LateUpdate()
{
if (isAutoRotating)
return;
if (target)
{
Scroll();
Move();
Rotate();
Quaternion rotation = Quaternion.Euler(y, x, z);
Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * disVector + target.position;
// 阻尼感
if (needDamping)
{
cam.transform.rotation = Quaternion.Lerp(cam.transform.rotation, rotation, Time.deltaTime * damping);
cam.transform.position = Vector3.Lerp(cam.transform.position, position, Time.deltaTime * damping);
}
else
{
cam.transform.rotation = rotation;
cam.transform.position = position;
}
}
}
void Move()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
if (Input.GetMouseButton(0))
{
float h = Input.GetAxis("Mouse X") * Time.deltaTime * xSpeed_move;
float v = Input.GetAxis("Mouse Y") * Time.deltaTime * ySpeed_move;
target.Translate(-h, 0, -v);
if (!isRangeClamped)
return;
float targetX = target.position.x;
targetX = Mathf.Clamp(targetX, xMinValue, xMaxValue);
float targetZ = target.position.z;
targetZ = Mathf.Clamp(targetZ, zMinValue, zMaxValue);
target.position = new Vector3(targetX, target.position.y, targetZ);
}
}
void Rotate()
{
if (Input.GetMouseButton(1))
{
// 判断是否需要反向旋转
if ((y > 90f && y < 270f) || (y < -90 && y > -270f))
{
x -= Input.GetAxis("Mouse X") * xSpeed_rotate;
}
else
{
x += Input.GetAxis("Mouse X") * xSpeed_rotate;
}
y -= Input.GetAxis("Mouse Y") * ySpeed_rotate;
x = ClampAngle(x, leftMax, rightMax);
y = ClampAngle(y, yMinLimit, yMaxLimit);
}
}
void Scroll()
{
distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed_scale;
distance = Mathf.Clamp(distance, minDistance, maxDistance);
xSpeed_move = distance / maxDistance * tempSpeed;
ySpeed_move = distance / maxDistance * tempSpeed;
}
// 对数值进行限制
float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
//如果限制活动范围 将区域范围绘制出来
if (isRangeClamped)
{
Handles.color = Color.cyan;
Vector3[] points = new Vector3[8]
{
new Vector3(xMinValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMaxValue),
new Vector3(xMinValue, 0, zMaxValue),
new Vector3(xMinValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMaxValue),
new Vector3(xMinValue, 0, zMaxValue)
};
for (int i = 0; i < 4; i++)
{
int start = i % 4;
int end = (i + 1) % 4;
Handles.DrawLine(points[start], points[end]);
Handles.DrawLine(points[start + 4], points[end + 4]);
Handles.DrawLine(points[start], points[i + 4]);
}
}
}
#endif
}