GQ_Communicate/GQ_URP/GQ/Assets/Scripts/Camera/CameraRT.cs

630 lines
19 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;
using static UnityEngine.GraphicsBuffer;
using Unity.VisualScripting;
/// <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 float zSpeed_move = 600;
public float yMinValue = -100f;
public float yMaxValue = 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;
float dotween_duration = 1f;
public void KillCameraDotween()
{
DOTween.Kill(transform, false);
DOTween.Kill(cameraTransform, false);
}
/// <summary>
/// 全景视角-None
/// </summary>
public void InitPanoramic()
{
auto_move = true;
ExtendedFlycam.Inst.cameraTypes = ExtendedFlycam.CameraTypes.;
Vector3 pos = Vector3.zero;
Vector3 rot = Vector3.zero;
Vector3 pos_target = Vector3.zero;
float _x = init_x;
float _y = init_y;
//Vector3 rot_target = Vector3.zero;
maxDistance = distance = 20;
if (CabinetUIManager.Instance.current_menu != Menu.M_数字机房_智能巡检)
{
switch (ExtendedFlycam.Inst.room)
{
case ExtendedFlycam.Room.None:
{
pos = camera_init_position;
rot = camera_init_eulerAngles;
pos_target = target_init_position;
_x = camera_init_eulerAngles.y;
_y = camera_init_eulerAngles.x;
}
break;
case ExtendedFlycam.Room.:
{
pos = new Vector3(9.53f, 15.23f, -5.71f);
rot = new Vector3(67.072f, 180, 0);
pos_target = new Vector3(9.67f, 1.878f, -11.1f);
_x = 180f;
_y = 67.072f;
distance = 15;
}
break;
case ExtendedFlycam.Room.:
{
pos = new Vector3(-4.218f, 15.8f, -5.9f);
rot = new Vector3(67.072f, 180, 0);
pos_target = new Vector3(-4.218f, 1.51f, -10.81f);
_x = 180f;
_y = 67.072f;
distance = 15;
}
break;
default:
break;
}
}
else
{
{
pos = new Vector3(-3.615f, 26.878f, -5.0f);
rot = new Vector3(90, 180, 0);
//pos_target = new Vector3(9.67f, 1.878f, -11.1f);
pos_target = new Vector3(-3.71f, 1.878f, -4.6f);
_x = 180;
_y = 90;
maxDistance = distance = 25;
}
}
if (Menu.M_全景监控_柜门状态 != CabinetUIManager.Instance.current_menu)
{
GameManager.Inst.power_close();
}
DOTween.Kill(transform, false);
DOTween.Kill(cameraTransform, false);
//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;
if (Menu.M_数字机房_接地网 != CabinetUIManager.Instance.current_menu)
{
for (int i = 0; i < GameManager.Inst.Cabinets_go.Count; i++)
{
GameManager.Inst.Cabinets_go[i].GetComponent<ClickEvent>().My_magnifyState = false;
GameManager.Inst.Cabinets_go[i].SetActive(true);
GameManager.Inst.Cabinets_go[i].GetComponent<TransparentGlow>().F2();
}
}
//PatternChoose.Inst.sb_bj_page.SetActive(false);
//PatternChoose.Inst.sb_xz_page.SetActive(false);
//PatternChoose.Inst.dk_bj_page.SetActive(false);
//PatternChoose.Inst.dk_xz_page.SetActive(false);
GameManager.Inst.magnifyState = false;
PatternChoose.Inst.clspup(CabinetUIManager.Instance.current_menu);
//GameManager.Inst.magnifyState = false;
//if (cam.transform.position == pos && cam.transform.eulerAngles == rot)
// return;
DOTween.To(() => x, (v) => x = v, _x, dotween_duration);
DOTween.To(() => y, (v) => y = v, _y, dotween_duration);
if (cam.transform.eulerAngles.z != 0)
{
var ea = cam.transform.eulerAngles;
ea.z = 0;
cam.transform.eulerAngles = ea;
}
DOTween.To(() => cam.transform.position, (v) => cam.transform.position = v, pos, dotween_duration);
DOTween.To(() => cam.transform.eulerAngles, v => cam.transform.eulerAngles = v, rot, dotween_duration);
//cam.transform.DORotateQuaternion();
DOTween.To(() => target.position, v => target.position = v, pos_target, dotween_duration);
DOTween.To(() => target.eulerAngles, v => target.eulerAngles = v, target_init_eulerAngles, dotween_duration).OnComplete(() =>
{
//Debug.Log("全景auto_move改变了");
auto_move = false;
});
}
/// <summary>
/// 鸟瞰视角-None
/// </summary>
public void InitBirds_Eye()
{
auto_move = true;
ExtendedFlycam.Inst.cameraTypes = ExtendedFlycam.CameraTypes.;
Vector3 pos = Vector3.zero;
Vector3 rot = Vector3.zero;
Vector3 pos_target = Vector3.zero;
float _x = 110; float _y = 15;
//Vector3 rot_target = Vector3.zero;
switch (ExtendedFlycam.Inst.room)
{
case ExtendedFlycam.Room.None:
{
pos = new Vector3(1, 2.8f, -7.5f);
rot = new Vector3(15, 110, 0);
pos_target = new Vector3(10.2f, 0.2f, -11);
distance = 10;
}
break;
case ExtendedFlycam.Room.:
{
pos = new Vector3(1, 2.8f, -7.5f);
rot = new Vector3(15, 110, 0);
pos_target = new Vector3(10.2f, 0.2f, -11);
distance = 10;
}
break;
case ExtendedFlycam.Room.:
{
pos = new Vector3(0.40f, 5.26f, -10.29f);
rot = new Vector3(44.9f, 240f, 0);
pos_target = new Vector3(-3.02f, 2, -10.85f);
_x = 240f;
_y = 44.9f;
distance = 4;
}
break;
default:
break;
}
DOTween.Kill(transform, false);
DOTween.Kill(cameraTransform, false);
for (int i = 0; i < GameManager.Inst.Cabinets_go.Count; i++)
{
GameManager.Inst.Cabinets_go[i].GetComponent<ClickEvent>().My_magnifyState = false;
GameManager.Inst.Cabinets_go[i].SetActive(true);
GameManager.Inst.Cabinets_go[i].GetComponent<TransparentGlow>().F2();
}
//PatternChoose.Inst.sb_bj_page.SetActive(false);
//PatternChoose.Inst.sb_xz_page.SetActive(false);
//PatternChoose.Inst.dk_bj_page.SetActive(false);
//PatternChoose.Inst.dk_xz_page.SetActive(false);
GameManager.Inst.magnifyState = true;
PatternChoose.Inst.clspup(CabinetUIManager.Instance.current_menu);
//GameManager.Inst.magnifyState = true;
DOTween.To(() => x, (v) => x = v, _x, dotween_duration);
DOTween.To(() => y, (v) => y = v, _y, dotween_duration);
DOTween.To(() => cam.transform.position, (v) => cam.transform.position = v, pos, dotween_duration);
DOTween.To(() => cam.transform.eulerAngles, v => cam.transform.eulerAngles = v, rot, dotween_duration);
DOTween.To(() => target.position, v => target.position = v, pos_target, dotween_duration);
DOTween.To(() => target.eulerAngles, v => target.eulerAngles = v, new Vector3(0, 110, 0), dotween_duration).OnComplete(() =>
{
//Debug.Log("鸟瞰auto_move改变了");
auto_move = false;
});
}
public Vector3 resume_position;
public float resume_distance;
public Quaternion resume_rotation;
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(Transform _target, float _distance, Quaternion rotation, float TargetPos_dis = -1)
{
target.position = _target.position;
if (TargetPos_dis == 0)
target.position += (Vector3.up);
else if (TargetPos_dis == 1)
target.position += ((Vector3.up) * 1.1f);
else if (TargetPos_dis == 2)
target.position -= ((Vector3.up) * 0.1f);
distance = _distance;
cameraTransform.rotation = rotation;
y = cameraTransform.eulerAngles.x;
x = cameraTransform.eulerAngles.y;
}
public void SetTarget(Vector3 _target, float _distance)
{
target.position = _target;
distance = _distance;
//y = _target.eulerAngles.x;
//x = _target.eulerAngles.y;
}
public void StoreTarget()
{
resume_position = target.position;
resume_distance = distance;
resume_rotation = cameraTransform.rotation;
}
public void ResumeTarget()
{
target.position = resume_position;
distance = resume_distance;
cameraTransform.rotation = resume_rotation;
y = cameraTransform.eulerAngles.x;
x = cameraTransform.eulerAngles.y;
}
Vector3 oldMousePos;
void Update()
{
//Debug.Log("\nauto_move: " + auto_move +
// "\nautoRotate: " + !autoRotate);
if (mask_img.activeSelf) return;
else if (!GameManager.Inst.isLoading) return;
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(GameManager.Inst.magnifyState);
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 GameObject mask_img;
//检测相机是否移动
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(bool _isup)
{
if (EventSystem.current.IsPointerOverGameObject())
return;
if (!_isup && 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);
}
else if (_isup && Input.GetMouseButton(2))
{
float v = Input.GetAxis("Mouse Y") * Time.deltaTime * zSpeed_move;
target.Translate(0, -v, 0);
if (!isRangeClamped)
return;
float targetY = target.position.y;
targetY = Mathf.Clamp(targetY, yMinValue, yMaxValue);
target.position = new Vector3(target.position.x, targetY, target.position.z);
}
}
bool is_on_ui;
void Rotate()
{
if (Input.GetMouseButtonDown(1))
{
is_on_ui = EventSystem.current.IsPointerOverGameObject();
}
if (Input.GetMouseButton(1) && !is_on_ui)
{
// 判断是否需要反向旋转
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()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed_scale;
distance = Mathf.Clamp(distance, minDistance, maxDistance);
xSpeed_move = distance / maxDistance * tempSpeed * 0.8f;
ySpeed_move = distance / maxDistance * tempSpeed * 0.8f;
}
// 对数值进行限制
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
}