美文网首页Unity教程合集unity3D技术分享
摄像机的移动跟随缩放旋转(优化方案)

摄像机的移动跟随缩放旋转(优化方案)

作者: 会杭 | 来源:发表于2016-09-08 16:19 被阅读0次

    当我们在用摄像机跟随目标物体移动时,可能还伴随着移动物体的旋转和场景的远近等等。那么问题来了,当我们旋转物体时,出现万象锁现象怎么办?!或者 同一物体 在进行多种操作时,旋转缩放移动等出现冲突怎么办?!
    干货来了,对摄像机操作优化来了!!!

    >干货来了!
    1.先创建五个空物体,按层级放置。分别体现 CameraController、RotateX、RotateY、ZoomZ、LookAt,把Camera 放在最下面.
    ##如下图:
    ![QQ图片20160908145740.png](https://img.haomeiwen.com/i2570889/5e27488d7551a8e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    2、在最上面控制器上创建脚本 CameraController.cs
    (思想:通过获取移动物体的transform 组件里面的 position、rotation的值,传递给CameraController摄像机,实现 摄像机 跟随 移动对象的 旋转缩放和移动。)
    代码如下:
    
      #region 单例
        private static CameraController instance;
        public static CameraController Instance
        {
            get {
                return instance;
            }
        }
        void Awake()
        {
            instance = this;
        }
        #endregion
    
        #region 序列化域
    
        [SerializeField]
        private Transform mCameraRotateX;
        [SerializeField]
        private Transform mCameraRotateY;
        [SerializeField]
        private Transform mCameraZoomZ;
        [SerializeField]
        private Transform mCameraLookAt;
    
        #endregion
    
    
        #region 属性
    
        private float sensitiveVal = 10f;
        private float rotateSensitiveVal = 60f;
        private float minValue = -10f;
        private float maxValue = -3f;
        #endregion
    
        #region 方法
    
        /// <summary>
        /// 摄像机跟随
        /// </summary>
        /// <param name="position"></param>
        public void AutoFollow(Vector3 position)
        {
            transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * sensitiveVal);
        }
    
        /// <summary>
        /// X轴跟随旋转 角度
        /// </summary>
        /// <param name="id">id  = 1 表示正方向,-1 表示负方向</param>
        public void RotateX(int id)
        {
            float value = Time.deltaTime * id * rotateSensitiveVal;
            mCameraRotateX.localEulerAngles += new Vector3(value, 0, 0); 
        }
        /// <summary>
        /// Y轴旋转角度
        /// </summary>
        /// <param name="id"> id = 1表示正方向,-1 表示负方向</param>
        public void RotateY(int id)
        {
            float value = Time.deltaTime * id * rotateSensitiveVal;
            mCameraRotateY.localEulerAngles += new Vector3(0, value, 0);
        }
        /// <summary>
        /// 指向 物体
        /// </summary>
        /// <param name="position"></param>
        public void LookAt(Vector3 position)
        {
            mCameraLookAt.LookAt(position);
        }
        /// <summary>
        /// 摄像机 跟随 Z轴 缩放缩放范围【-10,-3】
        /// </summary>
        /// <param name="id"></param>
        public void ZoomZ(int id)
        {
            float value =mCameraZoomZ.localPosition.z + Time.deltaTime * id * sensitiveVal;
            value = Mathf.Clamp(value, minValue, maxValue);
            mCameraZoomZ.localPosition = new Vector3(0, 0, value);
        }
        #endregion
    、、、、
    > 用到的数学函数为:
    1.Mathf.Clamp(float value, float min, float max);
    value 为默认值,其取值范围为[min,max]
    2.Vector3.Lerp(Vector3 a, Vector3 b, float t);
         表示:Linearly interpolates between two vectors.
                  两个向量之间的线性插值
    作用: 平滑跟随,防止出现卡顿或抖动现象
    3.transform.LocalEulerAngles
            // Summary:
            //     ///
            //     The rotation as Euler angles in degrees relative to the parent transform's rotation.
           //欧拉角的旋转度相对于父变换的旋转。
            //     ///
            public Vector3 localEulerAngles { get; set; }
    
    >简单的创建一个 移动对象Sphere,并把自身的相关transform参数 ,通过调用上面的方法来传递。
    
    
    ###代码:
    
    、、、、
    
      //定义变量
    
        float scrollWheel = 0f;
    
        float hor;
        float ver;
        void Update()
        {
            #region 用键盘控制  移动物体移动
    
            hor = Input.GetAxis("Horizontal");
            ver = Input.GetAxis("Vertical");
    
            transform.position += new Vector3(hor, 0, ver);
            #endregion
    
            #region 根据滚轮的前后滑动 缩放镜头
            scrollWheel = Input.GetAxis("Mouse ScrollWheel");
    
            if (scrollWheel != 0)
            {
                CameraController.Instance.ZoomZ(scrollWheel > 0 ? 1 : -1);
            }
            #endregion
    
            #region 当按下A时 摄像机绕物体正向旋转,当按下d时 摄像机绕物体对象 反向旋转
    
            if (Input.GetKey(KeyCode.Z))
            {
                CameraController.Instance.RotateY(1);
            }
            if (Input.GetKey(KeyCode.C))
            {
                CameraController.Instance.RotateY(-1);
            }
            #endregion
    
            #region 当按下X时 摄像机绕X轴旋转 正向旋转,当按下V时 摄像机 绕X轴反向旋转
    
            if (Input.GetKey(KeyCode.X))
            {
                CameraController.Instance.RotateX(1);
            }
            if (Input.GetKey(KeyCode.V))
            {
                CameraController.Instance.RotateX(-1);
            }
            #endregion
    
        }
    
        void LateUpdate()
        {
            //传递 移动对象 坐标参数,使摄像机 一直指向 移动对象,且跟随对象移动
            CameraController.Instance.LookAt(transform.position);
            CameraController.Instance.AutoFollow(transform.position);
        }
    
    
    
    、、、、

    相关文章

      网友评论

        本文标题:摄像机的移动跟随缩放旋转(优化方案)

        本文链接:https://www.haomeiwen.com/subject/aqbsettx.html