MotionCapture/Assets/CameraBehaviour.cs

147 lines
6.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
public class CameraBehaviour : MonoBehaviour
{
public Transform target;
private const int MouseWheelSensitivity = 1; //滚轮灵敏度设置
private const int MouseZoomMin = 1; //相机距离最小值
private const int MouseZoomMax = 20; //相机距离最大值
private const float XSpeed = 120.0f;
private const float YSpeed = 250.0f;
private const int YMinLimit = -360;
private const int YMaxLimit = 360;
private float _eulerX; //存储相机的euler角
private float _eulerY; //存储相机的euler角
private float _distance; //相机和target之间的距离因为相机的Z轴总是指向target也就是相机z轴方向上的距离
private Vector3 _targetOnScreenPosition; //目标的屏幕坐标第三个值为z轴距离
private Quaternion _cameraRotation; //存储相机的姿态四元数
private Vector3 _targetPosition; //target的位置
private Vector3 _initPosition; //平移时用于存储平移的起点位置
private Vector3 _cameraX; //相机的x轴方向向量
private Vector3 _cameraY; //相机的y轴方向向量
private Vector3 _initScreenPosition; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
private Vector3 _cursorScreenPosition; //当前鼠标的屏幕坐标(第三个值其实没什么用)
private Camera _mainCamera;
private void Start()
{
//这里就是设置一下初始的相机视角以及一些其他变量这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
var angles = transform.eulerAngles;
_eulerX = angles.x;
_eulerY = angles.y;
var position = target.position;
_targetPosition = position;
_cameraRotation = Quaternion.Euler(_eulerX, _eulerY, 0);
_distance = Vector3.Distance(position, transform.position);
// 引入中间变量 提高代码效率
var transform1 = transform;
//设置相机姿态
transform1.rotation = _cameraRotation;
//设置相机位置
transform1.position = _cameraRotation * new Vector3(0, 0, -_distance) + _targetPosition;
// 获得主摄像机
_mainCamera = Camera.main;
}
private void Update()
{
//鼠标右键旋转功能
if (Input.GetMouseButton(1))
{
// 鼠标控制需要反转X、Y轴
_eulerX += Input.GetAxis("Mouse Y") * XSpeed * 0.02f;
_eulerX = ClampAngle(_eulerX, YMinLimit, YMaxLimit);
_eulerY -= Input.GetAxis("Mouse X") * YSpeed * 0.02f;
_cameraRotation = Quaternion.Euler(_eulerX, _eulerY, 0);
var position = _cameraRotation * new Vector3(0.0f, 0.0f, -_distance) + _targetPosition;
// 引入中间变量 提高代码效率
var transform1 = transform;
transform1.rotation = _cameraRotation;
transform1.position = position;
}
if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
{
if (_distance is >= MouseZoomMin and <= MouseZoomMax)
{
_distance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
}
if (_distance < MouseZoomMin)
{
_distance = MouseZoomMin;
}
if (_distance > MouseZoomMax)
{
_distance = MouseZoomMax;
}
transform.position = _cameraRotation * new Vector3(0.0F, 0.0F, -_distance) + _targetPosition;
}
//鼠标中键平移
if (Input.GetMouseButtonDown(2))
{
// 添加中间变量
// 提高代码效率
var transform1 = transform;
_cameraX = transform1.right;
_cameraY = transform1.up;
_initScreenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetOnScreenPosition.z);
//targetOnScreenPosition.z为目标物体到相机平面的法线距离
_targetOnScreenPosition = _mainCamera.WorldToScreenPoint(_targetPosition);
_initPosition = _targetPosition;
}
if (Input.GetMouseButton(2))
{
_cursorScreenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetOnScreenPosition.z);
//0.01这个系数是控制平移的速度要根据相机和目标物体的distance来灵活选择
target.position = _initPosition - 0.01f * ((_cursorScreenPosition.x - _initScreenPosition.x) * _cameraX +
(_cursorScreenPosition.y - _initScreenPosition.y) * _cameraY);
//重新计算位置
var mPosition = _cameraRotation * new Vector3(0.0F, 0.0F, -_distance) + target.position;
transform.position = mPosition;
// //用这个会让相机的平移变得更平滑但是可能在你ButtonUp时未使相机移动到应到的位置导致再进行旋转与缩放操作时出现短暂抖动
//transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);
}
if (Input.GetMouseButtonUp(2))
{
//平移结束把cameraTargetPosition的位置更新一下不然会影响缩放与旋转功能
_targetPosition = target.position;
}
}
//将angle限制在min~max之间
private static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
/*void testScreenToWorldPoint()
{
//第三个坐标指的是在相机z轴指向方向上的距离
Vector3 screenPoint = Camera.main.WorldToScreenPoint(_targetPosition);
Debug.Log("ScreenPoint: " + screenPoint);
// var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
// Debug.Log("worldPosition: "+worldPosition);
}*/
}