Unity中摄像机绕物体旋转和拉近拉远视角的操作

    xiaoxiao2021-03-25  104

    Unity中摄像机的重要性毋庸置疑,关于摄像机的操作也有很多,比如第一人称跟随,第二人称跟随,摄像机的拉近拉远等等,下面就暂时实现摄像机的拉近拉远和旋转:

    创建新的场景,场景中添加一个cube,然后给cube添加新的脚本,脚本内容如下:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 using  UnityEngine; using  System.Collections;   public  class  TestCube : MonoBehaviour {      private  GameObject rotateObj;      private  GameObject camera;      public  float  speed = 3f;        private  bool  rotate =  false ;        public  float  maxView = 90;      public  float  minView = 10;      void  Start()      {          rotateObj = GameObject.Find( "Rotate" );          camera = GameObject.Find( "Main Camera" );      }      void  Update () {          //滑动鼠标滑轮控制视角的大小          float  offsetView = Input.GetAxis( "Mouse ScrollWheel" ) * speed;          float  tmpView = offsetView + Camera.main.fieldOfView;          tmpView = Mathf.Clamp(tmpView, minView, maxView);          Camera.main.fieldOfView = tmpView;            //绕主角旋转摄像机          if (rotate)          {              camera.transform.RotateAround(transform.position, Vector3.up, speed * Input.GetAxis( "Mouse X" ));          }          if (Input.GetMouseButtonDown(0))          {              rotate =  true ;          }          if (Input.GetMouseButtonUp(0))          {              rotate =  false ;          }      } } 当然啦其实围绕旋转的功能本身并不难:         // 拖动摄像机围绕物体旋转         if (Input.GetMouseButton(1))         {             x += Input.GetAxis("Mouse X") * speed * Time.deltaTime;             y += Input.GetAxis("Mouse Y") * speed * Time.deltaTime;             Quaternion q = Quaternion.Euler(y, x, 0);             Vector3 direction = q * Vector3.forward;             this.transform.position = center - direction * distance;             this.transform.LookAt(center);         } 用代码把摄像机移动到指定位置也不难:     public void MoveTo(Vector3 vecCenter, Vector3 vecPosition, float time)     {         // 设置缺省中心点         center = vecCenter;         defaultCenter = vecCenter;         defaultPositon = vecPosition;         distance = Vector3.Distance(defaultCenter, defaultPositon);         // 移动位置(用了DOTween做平滑)         Sequence seq = DOTween.Sequence();         seq.Append(this.transform.DOMove(vecPosition, time).SetEase(Ease.Linear));         seq.Play().OnUpdate(delegate         {             this.transform.LookAt(vecCenter);         });     } 困难的是,用代码移动之后,用户再用鼠标控制摄像机时,会出现视角跳跃的现象。 这个问题的核心在于,MoveTo() 的时候没有设置适当的 x 与 y 值,所以解决方案本来很简单,只要把这两个值设置一下就行了。 但是! 四元数的乘法是没有逆运算的! 也就是说,下面这一句求direction的代码不能逆运算: Vector3 direction = q * Vector3.forward; 当然其实办法还是有的,就像这样: Quaternion.FromToRotation(Vector3.forward, direction); 但算出来的 q 和原来的 q 长得不一样…… 为什么说“长得不一样”呢?因为这两个四元数本质上是等价的(但不要问我为什么,我的数学是体育老师教的…… 而且我还发现,q 和下面这个四元数对于【求direction的代码】也是等价的: Quaternion.Euler(q.eulerAngles.x, q.eulerAngles.y, 0); 于是问题就这样解决了,在 MoveTo() 中给 x 和 y 这样赋值:         // 计算 x,y 的值         distance = Vector3.Distance(vecCenter, vecPosition);         Vector3 direction = (vecCenter - vecPosition) / distance;         Quaternion q2 = Quaternion.FromToRotation(Vector3.forward, direction);         x = q2.eulerAngles.y;         y = q2.eulerAngles.x;
    转载请注明原文地址: https://ju.6miu.com/read-22904.html

    最新回复(0)