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;
}
}
}