272 lines
7.1 KiB
C#
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
|
|
}
|
|
|