221 lines
8.9 KiB
C#
221 lines
8.9 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using DG.Tweening;
|
|
/********************************************************************************
|
|
*Create By CG
|
|
*Function 摄像机环绕某个物体旋转展示
|
|
*鼠标滚轮:镜头远近-按住鼠标右键,拖动鼠标:摄像机绕某个物体上下左右旋转
|
|
*********************************************************************************/
|
|
namespace CG.UTility
|
|
{
|
|
public class CameraAroundCtrl : MonoBehaviour
|
|
{
|
|
/// <summary>
|
|
/// 需要围绕的物体
|
|
/// </summary>
|
|
public Transform _CenObj;
|
|
private float _rotSpeed = 5.12f;// 256.0f;
|
|
public float _RotSpeed { get => _rotSpeed /** ZXK.GYJQR.GameManager.Instance._CurMouseFlexible*/; }
|
|
|
|
private float _moveSpeed = 0.06f;// 3.0f;
|
|
public float _MoveSpeed { get => _moveSpeed /** ZXK.GYJQR.GameManager.Instance._CurMouseFlexible*/; }
|
|
|
|
private float _zoomSpeed = 1.6f;// 80.0f;
|
|
public float _ZoomSpeed { get => _zoomSpeed /** ZXK.GYJQR.GameManager.Instance._CurMouseFlexible*/; }
|
|
|
|
private float _minZoom = 2.0f;
|
|
private float _maxZoom = 100f;
|
|
private Vector2 _minViewPosXY = new Vector3(0.15f, 0.0f);
|
|
private Vector3 _maxViewPosXY = new Vector3(0.85f, 0.95f);
|
|
|
|
private float rotX = 0.0f;
|
|
private float rotY = 0.0f;
|
|
private float posX = 0.0f;
|
|
private float posY = 0.0f;
|
|
|
|
private float distance = 0.0f;
|
|
|
|
private float doubleClickIntervalTime = 0.25f;
|
|
private float clickTime = 0;
|
|
private int clickCount = 0;
|
|
private Vector3 _defaultCamPos;//相机初始位置
|
|
private Quaternion _defaultCamRot;
|
|
private float _defaultCamZoom;
|
|
private Vector3 _defaultCenObjPos;//目标点初始位置
|
|
private Quaternion _defaultCenObjRot;
|
|
|
|
private bool _cameraReNewState = false;//相机正在恢复初始位置
|
|
|
|
//是否禁止操作
|
|
[ReadOnly]
|
|
public bool _STRForbid = false;
|
|
[ReadOnly]//点击操作说明或者系统设置后,禁止操作
|
|
public bool _AllForbid = false;
|
|
|
|
private void OnEnable()
|
|
{
|
|
_defaultCamPos = transform.position;
|
|
_defaultCamRot = transform.rotation;
|
|
_defaultCenObjPos = _CenObj.position;
|
|
_defaultCenObjRot = _CenObj.rotation;
|
|
ResetCameraInit();
|
|
}
|
|
private void Update()
|
|
{
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
|
|
if (!PopUpMng._TriAble) return;
|
|
if (Input.GetMouseButtonDown(0) && !Physics.Raycast(ray, out RaycastHit rayHit)) // 鼠标左键点击//并且不能点击到物体
|
|
{
|
|
if (!_STRForbid && !EventSystem.current.IsPointerOverGameObject())
|
|
{// 鼠标点击在场景空白处
|
|
clickCount++;
|
|
if (clickCount == 2 && Time.time - clickTime < doubleClickIntervalTime)
|
|
{
|
|
WDebug.Log("空白处双击");
|
|
_cameraReNewState = true;
|
|
|
|
//摄像机回归原位,方案一
|
|
//Vector3[] temps = new Vector3[] { transform.position, _defaultCamPos };
|
|
//transform.DOPath(temps, 1.0f).SetLookAt(_CenObj);
|
|
//transform.DORotate(_defaultCamRot.eulerAngles, 1.0f);
|
|
|
|
//摄像机回归原位,方案二
|
|
_CenObj.SetParent(transform.parent);
|
|
transform.SetParent(_CenObj);
|
|
Sequence sequence = DOTween.Sequence();
|
|
sequence.Append(transform.GetComponent<Camera>().DOFieldOfView(_defaultCamZoom, 1.0f))
|
|
.Insert(0, _CenObj.DOMove(_defaultCenObjPos, 1.0f))
|
|
.Insert(0, _CenObj.DORotate(_defaultCenObjRot.eulerAngles, 1.0f))
|
|
.OnComplete(() =>
|
|
{
|
|
ResetCameraInit();
|
|
transform.SetParent(_CenObj.parent);
|
|
_CenObj.SetParent(transform);
|
|
});
|
|
clickCount = 0;
|
|
clickTime = 0;
|
|
}
|
|
clickTime = Time.time; // 更新点击时间
|
|
}
|
|
}
|
|
if (Time.time - clickTime > doubleClickIntervalTime)
|
|
{
|
|
clickCount = 0;
|
|
clickTime = 0;
|
|
}
|
|
|
|
|
|
if (!_STRForbid
|
|
&& EventSystem.current
|
|
&& !EventSystem.current.IsPointerOverGameObject()
|
|
&& !_cameraReNewState)
|
|
{
|
|
SetCamDistance();
|
|
SetCamPosition();
|
|
SetCamRotation();
|
|
}
|
|
}
|
|
public void ResetCameraInit()
|
|
{
|
|
transform.position = Vector3.right * -2.0f;
|
|
transform.rotation = Quaternion.Euler(0, 90, 0);
|
|
//if (ZXK.GYJQR.GameManager.Instance._DataBJCJHandler._ShowPartsName.Value.Equals(ConstCtrl.BJCZ_MAINMODEL1_NAME))
|
|
// _defaultCamZoom = 40;
|
|
//else
|
|
// _defaultCamZoom = 60;
|
|
transform.GetComponent<Camera>().fieldOfView = _defaultCamZoom;
|
|
Vector3 angles = transform.eulerAngles;
|
|
rotX = angles.y;
|
|
rotY = angles.x;
|
|
Vector3 pos = transform.localPosition;
|
|
posX = pos.x;
|
|
posY = pos.y;
|
|
distance = (transform.position - _CenObj.position).magnitude;
|
|
_cameraReNewState = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 物体独显时调用摄像机方法
|
|
/// </summary>
|
|
/// <param name="pos"></param>
|
|
/// <param name="size"></param>
|
|
public void CameraToTarget(Vector3 pos,float size)
|
|
{
|
|
_cameraReNewState = true;
|
|
_CenObj.SetParent(transform.parent);
|
|
transform.SetParent(_CenObj);
|
|
Sequence sequence = DOTween.Sequence();
|
|
sequence.Append(transform.GetComponent<Camera>().DOFieldOfView(size, 1.0f))
|
|
.Insert(0, _CenObj.DOMove(pos, 1.0f))
|
|
.OnComplete(() =>
|
|
{
|
|
transform.SetParent(_CenObj.parent);
|
|
_CenObj.SetParent(transform);
|
|
_cameraReNewState = false;
|
|
});
|
|
}
|
|
/// <summary>
|
|
/// 设置摄像机距离物体远近
|
|
/// </summary>
|
|
private void SetCamDistance()
|
|
{
|
|
//transform.localPosition += transform.forward * Input.mouseScrollDelta.y * Time.deltaTime * _ZoomSpeed;
|
|
//distance = (transform.position - _CenObj.position).magnitude;
|
|
|
|
float zoom = transform.GetComponent<Camera>().fieldOfView;
|
|
if (zoom < _minZoom && Input.mouseScrollDelta.y > 0 || zoom > _maxZoom && Input.mouseScrollDelta.y < 0)
|
|
{
|
|
return;
|
|
}
|
|
transform.GetComponent<Camera>().fieldOfView -= Input.mouseScrollDelta.y * Time.deltaTime * _ZoomSpeed;
|
|
}
|
|
/// <summary>
|
|
/// 平移摄像机
|
|
/// </summary>
|
|
private void SetCamPosition()
|
|
{
|
|
float mouse_x = Input.GetAxis("Mouse X");
|
|
float mouse_y = Input.GetAxis("Mouse Y");
|
|
if (Input.GetKey(KeyCode.Mouse1))
|
|
{
|
|
posX = mouse_x * _MoveSpeed * Time.deltaTime;
|
|
posY = mouse_y * _MoveSpeed * Time.deltaTime;
|
|
|
|
Vector2 viewPos = Camera.main.WorldToViewportPoint(_CenObj.position);
|
|
//WDebug.Log($"{viewPos.x}_{viewPos.y}");
|
|
if ((posY > 0 && viewPos.y > _maxViewPosXY.y) ||
|
|
(posY < 0 && viewPos.y < _minViewPosXY.y) ||
|
|
(posX > 0 && viewPos.x > _maxViewPosXY.x) ||
|
|
(posX < 0 && viewPos.x < _minViewPosXY.x))
|
|
{
|
|
return;
|
|
}
|
|
transform.Translate(new Vector3(-posX, -posY, 0), Space.Self);
|
|
distance = (transform.position - _CenObj.position).magnitude;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 设置摄像机围绕物体旋转
|
|
/// </summary>
|
|
private void SetCamRotation()
|
|
{
|
|
float mouse_x = Input.GetAxis("Mouse X");
|
|
float mouse_y = Input.GetAxis("Mouse Y");
|
|
if (Input.GetKey(KeyCode.Mouse0))
|
|
{
|
|
rotX += mouse_x * _RotSpeed * Time.deltaTime;
|
|
rotY -= mouse_y * _RotSpeed * Time.deltaTime;
|
|
rotY = Mathf.Clamp(rotY, -90, 90);//防止翻跟头
|
|
Quaternion rotation = Quaternion.Euler(rotY, rotX, 0);//利用欧拉角防止万向锁
|
|
Vector3 position = rotation * new Vector3(0, 0, -distance) + _CenObj.position;//求得旋转后位置
|
|
transform.rotation = rotation;
|
|
transform.position = position;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|