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

412 lines
12 KiB
C#

using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.EventSystems;
using DG.Tweening;
using System;
using static WebInteraction;
/// <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 Awake()
{
BoolMonitor.ValueChanged += BoolMonitor_ValueChanged;
}
private static void BoolMonitor_ValueChanged(object sender, EventArgs e)
{
//Debug.Log("当前是否不动" + BoolMonitor.Value);
if (!BoolMonitor.Value)
{
if (!string.IsNullOrEmpty(WebInteraction.Inst.current_videoNumber) && WebInteraction.Inst.isVideoPlay)
{
WebInteraction.Inst.CloseVideo(WebInteraction.Inst.current_videoNumber);
}
}
}
private void Start()
{
if (cam == null)
{
cam = Camera.main;
}
cameraTransform = cam.transform;
// 初始化上一帧的位置和旋转
lastPosition = cameraTransform.position;
lastRotation = cameraTransform.rotation;
target = transform.GetChild(0);
target.gameObject.AddComponent<CameraTargetFollowCam>();
target_init_position = target.position;
//target_init_rotation = target.rotation;
target_init_eulerAngles = target.eulerAngles;
camera_init_position = cam.transform.position;
//camera_init_rotation = cam.transform.rotation;
camera_init_eulerAngles = cam.transform.eulerAngles;
init_x = x = cam.transform.localEulerAngles.y;
init_y = y = cam.transform.localEulerAngles.x;
tempSpeed = xSpeed_move;
rotateTimer_temp = rotateTimer;
}
Vector3 target_init_position;
//Quaternion target_init_rotation;
Vector3 target_init_eulerAngles;
Vector3 camera_init_position;
//Quaternion camera_init_rotation;
Vector3 camera_init_eulerAngles;
float init_x;
float init_y;
bool auto_move;
/// <summary>
/// 全景视角
/// </summary>
public void InitPanoramic()
{
auto_move = true;
//target.position = target_init_position;
//target.rotation = target_init_rotation;
//cam.transform.position = camera_init_position;
//cam.transform.rotation = camera_init_rotation;
//x = cam.transform.localEulerAngles.y;
//y = cam.transform.localEulerAngles.x;
Array.ForEach(GameObject.FindObjectsOfType<ClickEvent>(), itme =>
{
itme.My_magnifyState = false;
});
//Array.ForEach(GameObject.FindObjectsOfType<TransparentGlow>(), itme =>
//{
// itme.F2();
//});
PatternChoose.Inst.transform.Find("设备类/设备配置").gameObject.SetActive(false);
PatternChoose.Inst.transform.Find("设备类/设备新增").gameObject.SetActive(false);
PatternChoose.Inst.transform.Find("端口类/端口配置").gameObject.SetActive(false);
PatternChoose.Inst.transform.Find("端口类/端口新增").gameObject.SetActive(false);
GameManager.Inst.magnifyState = false;
distance = 20;
DOTween.To(() => x, (v) => x = v, init_x, 0.5f);
DOTween.To(() => y, (v) => y = v, init_y, 0.5f);
DOTween.To(() => cam.transform.position, (v) => cam.transform.position = v, camera_init_position, 0.5f);
DOTween.To(() => cam.transform.eulerAngles, v => cam.transform.eulerAngles = v, camera_init_eulerAngles, 0.5f);
DOTween.To(() => target.position, v => target.position = v, target_init_position, 0.5f);
DOTween.To(() => target.eulerAngles, v => target.eulerAngles = v, target_init_eulerAngles, 0.5f).OnComplete(() => { auto_move = false; });
}
/// <summary>
/// 鸟瞰视角
/// </summary>
public void InitBirds_Eye()
{
auto_move = true;
Array.ForEach(GameObject.FindObjectsOfType<ClickEvent>(), itme =>
{
itme.My_magnifyState = false;
});
PatternChoose.Inst.transform.Find("设备类/设备配置").gameObject.SetActive(false);
PatternChoose.Inst.transform.Find("设备类/设备新增").gameObject.SetActive(false);
PatternChoose.Inst.transform.Find("端口类/端口配置").gameObject.SetActive(false);
PatternChoose.Inst.transform.Find("端口类/端口新增").gameObject.SetActive(false);
GameManager.Inst.magnifyState = true;
distance = 10;
DOTween.To(() => x, (v) => x = v, 110, 0.5f);
DOTween.To(() => y, (v) => y = v, 15, 0.5f);
DOTween.To(() => cam.transform.position, (v) => cam.transform.position = v, new Vector3(1, 2.8f, -7.5f), 0.5f);
DOTween.To(() => cam.transform.eulerAngles, v => cam.transform.eulerAngles = v, new Vector3(15, 110, 0), 0.5f);
DOTween.To(() => target.position, v => target.position = v, new Vector3(10.2f, 0.2f, -11), 0.5f);
DOTween.To(() => target.eulerAngles, v => target.eulerAngles = v, new Vector3(0, 110, 0), 0.5f).OnComplete(() => { auto_move = false; });
}
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()
{
BoolMonitor.Value = ismove();
if (auto_move)
return;
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 (auto_move)
return;
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;
}
}
}
private Transform cameraTransform;
private Vector3 lastPosition;
private Quaternion lastRotation;
//检测相机是否移动
public bool ismove()
{
// 检查当前帧的位置和旋转是否与上一帧不同
if (cameraTransform.position != lastPosition || cameraTransform.rotation != lastRotation)
{
// 相机移动了,可以在这里执行相应的操作
//Debug.Log("相机移动了"+ BoolMonitor.Value);
// 更新上一帧的位置和旋转
lastPosition = cameraTransform.position;
lastRotation = cameraTransform.rotation;
return false;
}
return true;
}
void Move()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
if (Input.GetMouseButton(2))
{
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
}