using System.Collections; using System.Collections.Generic; using MyFrameworkPure; using UnityEngine; #if STEAMVR using HTC.UnityPlugin.Vive; #endif namespace CommonScript { public enum MouseButton { Left = 0, Right, Middle, } /// /// 相机旋转的通用脚本 /// public class CameraRotator : MonoBehaviour { [Header("鼠标输入")] [SerializeField] private bool enableMouseInput = true; [SerializeField] private MouseButton mouseButton = MouseButton.Left; [SerializeField] private float mouseRotSpeed = 5; [Header("触屏输入")] [SerializeField] private bool enableTouchInput = true; #if STEAMVR [Header("Vive输入")] [SerializeField] private bool enableViveInput = true; [SerializeField] private ViveRoleProperty viveRoleProperty = ViveRoleProperty.New(HandRole.RightHand); [SerializeField] private float viveRotSpeed = 30; #endif [Header("其他参数")] [SerializeField] private Transform cameraTransform; [SerializeField] private Transform target; [SerializeField] private bool lookatTarget = true; [SerializeField] private bool allowZoom = true; [SerializeField] private float zoomSpeed = 50; [SerializeField] private float farestToTarget = 3000f; [SerializeField] private float nearestToTarget = 0f; [SerializeField] private bool clampEuler = true; [SerializeField] private float minEulerX = 0; [SerializeField] private float maxEulerX = 180; [SerializeField] private float minEulerY = -180; [SerializeField] private float maxEulerY = 180; public Transform target_yinyong; private Vector3 lastMousePos; private Vector2 lastTouchPos; private Vector3 lastCameraPos; private Vector3 lastCameraRot; // Start is called before the first frame update void Start() { cameraTransform = cameraTransform != null?cameraTransform:transform; SetTarget(target); } // Update is called once per frame void Update() { if (enableMouseInput) HandleMouseInput(); if (enableTouchInput) HandleTouchInput(); //if (enableViveInput) // HandleViveInput(); if (clampEuler) ClampEuler(); if (lookatTarget && target) { cameraTransform.LookAt(target); } if (allowZoom && target) { ClameDistanceToTarget(); } RecordCameraTransform(); } public void SetTarget(Transform target) { //校验目标物合法性 if (target) { float distance = Vector3.Distance(cameraTransform.position, target.position); if (allowZoom && (distance > farestToTarget || distance < nearestToTarget)) { Debug.LogError("相机初始位置不满足要求!"); return; } Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles); if (clampEuler && (euler.x < minEulerX || euler.x > maxEulerX)) { Debug.LogError("相机旋转X分量不满足要求"); return; } if (clampEuler && (euler.y < minEulerY || euler.y > maxEulerY)) { Debug.LogError("相机旋转Y分量不满足要求"); return; } } else { if (allowZoom || lookatTarget) { Debug.LogError("开启相机缩放或朝向目标开关,要求目标物不能为空!"); return; } } this.target = target; RecordCameraTransform(); target_yinyong = target; } void HandleMouseInput() { if (Input.GetMouseButtonDown((int)mouseButton)) { lastMousePos = Input.mousePosition; } if (Input.GetMouseButton((int)mouseButton)) { Vector3 delta = Input.mousePosition - lastMousePos; if (target) { cameraTransform.RotateAround(target.position,-cameraTransform.right, delta.y * mouseRotSpeed * Time.deltaTime); ClampPosFromEulerX(); cameraTransform.RotateAround(target.position,Vector3.up,delta.x * mouseRotSpeed * Time.deltaTime); ClampPosFromEulerY(); } else { cameraTransform.Rotate(Vector3.left * delta.y * mouseRotSpeed * Time.deltaTime, Space.Self); cameraTransform.Rotate(Vector3.up * delta.x * mouseRotSpeed * Time.deltaTime, Space.World); } lastMousePos = Input.mousePosition; } if (allowZoom) { float mouseScroll = Input.GetAxis("Mouse ScrollWheel"); cameraTransform.Translate(Vector3.forward * mouseScroll * zoomSpeed * Time.deltaTime); } } void HandleTouchInput() { if(Input.touchCount == 0) return; Touch touch = Input.GetTouch(0); if (touch.phase == TouchPhase.Began) { lastTouchPos = touch.position; } else if(touch.phase == TouchPhase.Moved) { Vector3 delta = touch.position - lastTouchPos; if (target) { cameraTransform.RotateAround(target.position, -cameraTransform.right, delta.y * mouseRotSpeed * Time.deltaTime); ClampPosFromEulerX(); cameraTransform.RotateAround(target.position, Vector3.up, delta.x * mouseRotSpeed * Time.deltaTime); ClampPosFromEulerY(); } else { cameraTransform.Rotate(Vector3.left * delta.y * mouseRotSpeed * Time.deltaTime, Space.Self); cameraTransform.Rotate(Vector3.up * delta.x * mouseRotSpeed * Time.deltaTime, Space.World); } lastTouchPos = touch.position; } } void HandleViveInput() { #if STEAMVR Vector2 pressPos = HTC.UnityPlugin.Vive.ViveInput.GetPadPressAxis(viveRoleProperty); if(Vector2.Distance(Vector2.zero,pressPos) < 0.01f) return; //将触摸板位置划分上下左右四块区域 float angle = Vector2.SignedAngle(Vector2.right, pressPos); if (angle > -45 && angle <= 45) { pressPos = Vector2.right; } else if(angle > 45 && angle <=135) { pressPos = Vector2.up; } else if(angle > 135 || angle < -135) { pressPos = Vector2.left; } else { pressPos = Vector2.down; } if (target) { cameraTransform.RotateAround(target.position, -cameraTransform.right, pressPos.y * viveRotSpeed * Time.deltaTime); ClampPosFromEulerX(); cameraTransform.RotateAround(target.position, Vector3.up, pressPos.x * viveRotSpeed * Time.deltaTime); ClampPosFromEulerY(); } else { cameraTransform.Rotate(Vector3.left * pressPos.y * viveRotSpeed * Time.deltaTime, Space.Self); cameraTransform.Rotate(Vector3.up * pressPos.x * viveRotSpeed * Time.deltaTime, Space.World); } #endif } /// /// 限制相机旋转角度 /// void ClampEuler() { Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles); euler = new Vector3(Mathf.Clamp(euler.x,minEulerX,maxEulerX),Mathf.Clamp(euler.y,minEulerY,maxEulerY),0); cameraTransform.eulerAngles = euler; } void ClampPosFromEulerX() { Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles); if (euler.x < minEulerX || euler.x > maxEulerX) { RestoreCameraTransform(); } } void ClampPosFromEulerY() { Vector3 euler = VectorTool.ConvertToEuler180(cameraTransform.eulerAngles); if (euler.y < minEulerY || euler.y > maxEulerY) { RestoreCameraTransform(); } } /// /// 限制相机到目标的距离 /// void ClameDistanceToTarget() { float distance = Vector3.Distance(cameraTransform.position, target.position); if (distance < nearestToTarget || distance > farestToTarget) { RestoreCameraTransform(); } } /// /// 记录相机的变换信息 /// void RecordCameraTransform() { lastCameraPos = cameraTransform.transform.position; lastCameraRot = cameraTransform.transform.eulerAngles; } /// /// 恢复相机变换到上一帧 /// void RestoreCameraTransform() { cameraTransform.position = lastCameraPos; cameraTransform.eulerAngles = lastCameraRot; } } }