feature: 添加旋转、平移、缩放摄像头功能
This commit is contained in:
		
							
								
								
									
										145
									
								
								Assets/CameraBehaviour.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								Assets/CameraBehaviour.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | |||||||
|  | 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 = 250.0f; | ||||||
|  |     private const float YSpeed = 120.0f; | ||||||
|  | 
 | ||||||
|  |     private const int YMinLimit = -360; | ||||||
|  |     private const int YMaxLimit = 360; | ||||||
|  | 
 | ||||||
|  |     private float _eulerX; //存储相机的euler角 | ||||||
|  |     private float _eulerY; //存储相机的euler角 | ||||||
|  | 
 | ||||||
|  |     private float _distance = 5; //相机和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 _cameraZ; //相机的z轴方向向量 | ||||||
|  | 
 | ||||||
|  |     private Vector3 _initScreenPosition; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用) | ||||||
|  |     private Vector3 _cursorScreenPosition; //当前鼠标的屏幕坐标(第三个值其实没什么用) | ||||||
|  | 
 | ||||||
|  |     private void Start() | ||||||
|  |     { | ||||||
|  |         //这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应 | ||||||
|  |         var angles = transform.eulerAngles; | ||||||
|  |         _eulerX = angles.y; | ||||||
|  |         _eulerY = angles.x; | ||||||
|  |         _targetPosition = target.position; | ||||||
|  |         _cameraRotation = Quaternion.Euler(_eulerY + 60, _eulerX, 0); | ||||||
|  |         // 引入中间变量 提高代码效率 | ||||||
|  |         var transform1 = transform; | ||||||
|  |         transform1.rotation = _cameraRotation; //设置相机姿态 | ||||||
|  |         /*var position = | ||||||
|  |             _cameraRotation * new Vector3(0.0F, 0.0F, -_distance) + | ||||||
|  |             _targetPosition; //四元数表示一个旋转,四元数乘以向量相当于把向量旋转对应角度,然后加上目标物体的位置就是相机位置了*/ | ||||||
|  |         transform1.position = _cameraRotation * new Vector3(0, 0, -_distance) + _targetPosition; //设置相机位置 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void Update() | ||||||
|  |     { | ||||||
|  |         //鼠标右键旋转功能 | ||||||
|  |         if (Input.GetMouseButton(1)) | ||||||
|  |         { | ||||||
|  |             _eulerX += Input.GetAxis("Mouse X") * XSpeed * 0.02f; | ||||||
|  |             _eulerY -= Input.GetAxis("Mouse Y") * YSpeed * 0.02f; | ||||||
|  | 
 | ||||||
|  |             _eulerY = ClampAngle(_eulerY, YMinLimit, YMaxLimit); | ||||||
|  | 
 | ||||||
|  |             _cameraRotation = Quaternion.Euler(_eulerY + 60, _eulerX, 0); | ||||||
|  |             var position = _cameraRotation * new Vector3(0.0f, 0.0f, -_distance) + _targetPosition; | ||||||
|  | 
 | ||||||
|  |             // 引入中间变量 提高代码效率 | ||||||
|  |             var transform1 = transform; | ||||||
|  |             transform1.rotation = _cameraRotation; | ||||||
|  |             transform1.position = position; | ||||||
|  |         } | ||||||
|  |         else if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能 | ||||||
|  |         { | ||||||
|  |             if (_distance >= MouseZoomMin && _distance <= 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; | ||||||
|  |             _cameraZ = transform1.forward; | ||||||
|  | 
 | ||||||
|  |             _initScreenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, _targetOnScreenPosition.z); | ||||||
|  | 
 | ||||||
|  |             //targetOnScreenPosition.z为目标物体到相机平面的法线距离 | ||||||
|  |             _targetOnScreenPosition = Camera.main!.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)) | ||||||
|  |         { | ||||||
|  |             Debug.Log("upOnce"); | ||||||
|  |             //平移结束把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); | ||||||
|  |     }*/ | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								Assets/CameraBehaviour.cs.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/CameraBehaviour.cs.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | fileFormatVersion: 2 | ||||||
|  | guid: 9189b565e8ba9bfc3bdaa38149e3e13f | ||||||
|  | MonoImporter: | ||||||
|  |   externalObjects: {} | ||||||
|  |   serializedVersion: 2 | ||||||
|  |   defaultReferences: [] | ||||||
|  |   executionOrder: 0 | ||||||
|  |   icon: {instanceID: 0} | ||||||
|  |   userData:  | ||||||
|  |   assetBundleName:  | ||||||
|  |   assetBundleVariant:  | ||||||
| @@ -339,6 +339,7 @@ GameObject: | |||||||
|   - component: {fileID: 963194228} |   - component: {fileID: 963194228} | ||||||
|   - component: {fileID: 963194227} |   - component: {fileID: 963194227} | ||||||
|   - component: {fileID: 963194226} |   - component: {fileID: 963194226} | ||||||
|  |   - component: {fileID: 963194229} | ||||||
|   m_Layer: 0 |   m_Layer: 0 | ||||||
|   m_Name: Main Camera |   m_Name: Main Camera | ||||||
|   m_TagString: MainCamera |   m_TagString: MainCamera | ||||||
| @@ -412,6 +413,19 @@ Transform: | |||||||
|   m_Father: {fileID: 0} |   m_Father: {fileID: 0} | ||||||
|   m_RootOrder: 0 |   m_RootOrder: 0 | ||||||
|   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | ||||||
|  | --- !u!114 &963194229 | ||||||
|  | MonoBehaviour: | ||||||
|  |   m_ObjectHideFlags: 0 | ||||||
|  |   m_CorrespondingSourceObject: {fileID: 0} | ||||||
|  |   m_PrefabInstance: {fileID: 0} | ||||||
|  |   m_PrefabAsset: {fileID: 0} | ||||||
|  |   m_GameObject: {fileID: 963194225} | ||||||
|  |   m_Enabled: 1 | ||||||
|  |   m_EditorHideFlags: 0 | ||||||
|  |   m_Script: {fileID: 11500000, guid: 9189b565e8ba9bfc3bdaa38149e3e13f, type: 3} | ||||||
|  |   m_Name:  | ||||||
|  |   m_EditorClassIdentifier:  | ||||||
|  |   target: {fileID: 320693310} | ||||||
| --- !u!1 &1880773849 | --- !u!1 &1880773849 | ||||||
| GameObject: | GameObject: | ||||||
|   m_ObjectHideFlags: 0 |   m_ObjectHideFlags: 0 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user