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 { /// /// 需要围绕的物体 /// 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().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().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; } /// /// 物体独显时调用摄像机方法 /// /// /// public void CameraToTarget(Vector3 pos,float size) { _cameraReNewState = true; _CenObj.SetParent(transform.parent); transform.SetParent(_CenObj); Sequence sequence = DOTween.Sequence(); sequence.Append(transform.GetComponent().DOFieldOfView(size, 1.0f)) .Insert(0, _CenObj.DOMove(pos, 1.0f)) .OnComplete(() => { transform.SetParent(_CenObj.parent); _CenObj.SetParent(transform); _cameraReNewState = false; }); } /// /// 设置摄像机距离物体远近 /// private void SetCamDistance() { //transform.localPosition += transform.forward * Input.mouseScrollDelta.y * Time.deltaTime * _ZoomSpeed; //distance = (transform.position - _CenObj.position).magnitude; float zoom = transform.GetComponent().fieldOfView; if (zoom < _minZoom && Input.mouseScrollDelta.y > 0 || zoom > _maxZoom && Input.mouseScrollDelta.y < 0) { return; } transform.GetComponent().fieldOfView -= Input.mouseScrollDelta.y * Time.deltaTime * _ZoomSpeed; } /// /// 平移摄像机 /// 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; } } /// /// 设置摄像机围绕物体旋转 /// 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; } } } }