Unity基础包 FirstPersonController下的MouseLook 脚本研究

发表于2017-11-08
评论0 795浏览

今天主要给大家介绍下FirstPersonController下的MouseLook脚本,主要是处理人物和镜头的旋转:


下面是代码:

  1. public class MouseLook  
  2. {  
  3.     public float XSensitivity = 2f; //x轴和y轴的灵敏度  
  4.     public float YSensitivity = 2f;  
  5.   
  6.     public bool clampVerticalRotation = true;   //是否锁定x轴的旋转角度,旋转的解释见下  
  7.     public float MinimumX = -90F;   //锁定的最小、最大角度  
  8.     public float MaximumX = 90F;  
  9.   
  10.     public bool smooth; //是否使用插值运算  
  11.     public float smoothTime = 5f;   //插值的时间  
  12.   
  13.     public bool lockCursor = true;  //是否要检测锁定指针  
  14.   
  15.   
  16.     private Quaternion m_CharacterTargetRot;    //角色和相机的目标旋转角度  
  17.     private Quaternion m_CameraTargetRot;  
  18.   
  19.     private bool m_cursorIsLocked = true;   //当前鼠标指针是否锁定,只有lockCursor为true的时候,该值才会有效  
  20.   
  21.     // 初始化,传入角色和相机的旋转角度  
  22.     public void Init(Transform character, Transform camera)  
  23.     {  
  24.         m_CharacterTargetRot = character.localRotation; //角色的旋转角度  
  25.         m_CameraTargetRot = camera.localRotation;   //相机的旋转角度  
  26.     }  
  27.   
  28.     // FirstPersonController每帧会调用  
  29.     // 根据鼠标移动的位置调整镜头的旋转  
  30.     public void LookRotation(Transform character, Transform camera)  
  31.     {  
  32.         // 获取鼠标的位置,乘以灵敏度,获取x轴y轴的旋转  
  33.         // 注意这边的位置是相对位置,也就是这一帧和上一帧的相对移动位置  
  34.         float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;     
  35.         float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;  
  36.   
  37.         // 旋转,y轴旋转角色,x轴旋转镜头,也就是说横向的旋转是旋转的角色,而纵向的旋转是旋转镜头。  
  38.         // 这里有个好处,就是镜头Camera节点是在FPC节点下面的,所以旋转了角色的同时也会旋转镜头,同时兼顾了旋转角色的正方向。  
  39.         // 而纵向的旋转,其实对实际角色而言没有任何影响,所以只要旋转镜头即可,这种分层次的旋转十分有用。  
  40.         m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);    //然后说一下这边API的使用,大家刚看到一个乘法,可能跟我一样有些懵逼,不过这边乘以一个欧拉角,相当于旋转增加该值,而增加的就是Transform面板上Rotation的值了,所以要使用面板Rotation值的话一定要记住使用欧拉角,而不是普通的创建,普通的创建那是四元数  
  41.         m_CameraTargetRot *= Quaternion.Euler(-xRot, 0f, 0f);  
  42.   
  43.         // 锁定x轴的旋转角度  
  44.         if(clampVerticalRotation)  
  45.             m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);  
  46.   
  47.         if(smooth)  //使用插值运算平滑旋转速度,不过我打开了感觉头晕,不知道为什么。第三人称用这类插值运算应该很舒服。  
  48.         {  
  49.             // Slerp使用球形进行插值  
  50.             character.localRotation = Quaternion.Slerp (character.localRotation, m_CharacterTargetRot,  
  51.                 smoothTime * Time.deltaTime);  
  52.             camera.localRotation = Quaternion.Slerp (camera.localRotation, m_CameraTargetRot,  
  53.                 smoothTime * Time.deltaTime);  
  54.         }  
  55.         else     //直接赋值  
  56.         {  
  57.             character.localRotation = m_CharacterTargetRot;  
  58.             camera.localRotation = m_CameraTargetRot;  
  59.         }  
  60.   
  61.         UpdateCursorLock();  
  62.     }  
  63.   
  64.     public void SetCursorLock(bool value)  
  65.     {  
  66.         lockCursor = value;  
  67.         if(!lockCursor)  
  68.         {  
  69.             // 如果用户主动设置lockCursor,即InternalLockUpdate不会影响是否锁定指针,则我们强制解锁指针  
  70.             // 也就是说,lockCursor为true时快捷键影响锁定指针,lockCursor为false的时候快捷键不影响,并强制不锁指针  
  71.             Cursor.lockState = CursorLockMode.None;  
  72.             Cursor.visible = true;  
  73.         }  
  74.     }  
  75.   
  76.     // 鼠标指针锁定有关,FirstPersonController的Update中会调用一次外,MouseLook的LookRotation中也会调用一次  
  77.     public void UpdateCursorLock()  
  78.     {  
  79.         //如果设置lockCursor,则检查确认是否要锁定指针  
  80.         if (lockCursor)  
  81.             InternalLockUpdate();  
  82.     }  
  83.   
  84.     private void InternalLockUpdate()  
  85.     {  
  86.         if(Input.GetKeyUp(KeyCode.Escape))  //按下esc,退出指针锁定  
  87.         {  
  88.             m_cursorIsLocked = false;  
  89.         }  
  90.         else if(Input.GetMouseButtonUp(0))  //按下鼠标左键,指针锁定  
  91.         {  
  92.             m_cursorIsLocked = true;  
  93.         }  
  94.   
  95.         if (m_cursorIsLocked)  
  96.         {  
  97.             Cursor.lockState = CursorLockMode.Locked;   //指针状态变为锁定  
  98.             Cursor.visible = false//并隐藏  
  99.         }  
  100.         else if (!m_cursorIsLocked)  
  101.         {  
  102.             Cursor.lockState = CursorLockMode.None; //释放鼠标指针  
  103.             Cursor.visible = true;  
  104.         }  
  105.     }  
  106.   
  107.     // 锁定镜头的旋转角度,镜头只跟X轴旋转有关  
  108.     Quaternion ClampRotationAroundXAxis(Quaternion q)  
  109.     {  
  110.         // 嗯,网上看了半天的四元数,没太理解就不强行解释了,等过段时间研究一下矩阵和四元数  
  111.         q.x /= q.w;  
  112.         q.y /= q.w;  
  113.         q.z /= q.w;  
  114.         q.w = 1.0f;  
  115.   
  116.         float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);  
  117.   
  118.         angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);  
  119.   
  120.         q.x = Mathf.Tan (0.5f * Mathf.Deg2Rad * angleX);  
  121.   
  122.         return q;  
  123.     }  
  124.   
  125. }  

OK,我会继续分析基础包中剩下的代码的,同时也会加把劲把Unity书中基础部分给刷掉。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论