zoukankan      html  css  js  c++  java
  • 一个摄像机控制类的总结

    一个摄像机控制类的总结


    实现功能:

            通过鼠标的操纵,控制摄像机围绕模型对象旋转,从而进行对模型对象的观察。

    设计思路:

            首先依据摄像机的当前方位。计算它应该到达的目标方位;

            然后通过插值运算,将摄像机逐帧移动到该目标方位。

     

    过程描写叙述:

    1、 计算摄像机的目标方位。

     

            先计算摄像机本地坐标系轴向与世界坐标系轴向的夹角,作为方位的初始值。注意。这里仅仅取摄像机须要旋转变化的坐标轴就可以,这里我们用的是X和Y轴。

     

            在鼠标的控制过程中,实时的改动此夹角值。

     

            对改动后的夹角值进行限位处理,使之满足我们的须要。

     

            将限位处理后的夹角值由欧拉角的表示形式转换到四元数的表示形式,作为摄像机的目标方位保存。

          

    2、 通过在摄像机的当前方位与目标方位间做插值运算,以一定的速度将摄像机向目标方位移动。

     

    源码:绑定在摄像机对象之上

          

        ///<summary>

        ///旋转轴的变换组件(模型对象)

        ///</summary>

        public Transform _tfmRotAxis;

        ///<summary>

        ///摄像机的移动缓冲

        ///</summary>

        public float _fZoomDmp = 5f;

        ///<summary>

        ///摄像机的移动速度

        ///</summary>

        public float _fZoomRate = 240f;

        ///<summary>

        ///鼠标X方向移动灵敏度

        ///</summary>

        public float _fXSpe = 6f;

        ///<summary>

        ///鼠标Y方向移动灵敏度

        ///</summary>

        public float _fYSpe = 6f;

        ///<summary>

        ///鼠标X方向最小角度限位

        ///</summary>

        public float _fMinLimitX = -360f;

        ///<summary>

        ///鼠标X方向最大角度限位

        ///</summary>

        public float _fMaxLimitX = 360f;

        ///<summary>

        ///鼠标Y方向最小角度限位

        ///</summary>

        public float _fMinLimitY = -360f;

        ///<summary>

        ///鼠标Y方向最大角度限位

        ///</summary>

        public float _fMaxLimitY = 360f;

        ///<summary>

        ///摄像机距旋转轴的近期距离

        ///</summary>

        public float _fMinDist = 0f;

        ///<summary>

        ///摄像机距旋转轴的最远距离

        ///</summary>

        public float _fMaxDist = 20f;

        ///<summary>

        ///移动的偏移量

        ///</summary>

        public Vector3 _vec3TarOffset;

    //------------------------------ Private ----------------------------------

        ///<summary>

        ///摄像机的变换组件

        ///</summary>

        private Transform _tfmThis;

        ///<summary>

        ///摄像机到旋转轴的当前距离

        ///</summary>

        private float _fCurtDist;

        ///<summary>

        ///摄像机到旋转轴的目标距离

        ///</summary>

        private float _fTarDist;

        ///<summary>

        ///摄像机的目标朝向(方位)

        ///</summary>

        private Quaternion _quaTarRtn;

        ///<summary>

        ///摄像机X轴与世界坐标X轴的夹角

        ///</summary>

        private float _fXDgre;

        ///<summary>

        ///摄像机Y轴与世界坐标Y轴的夹角

        ///</summary>

        private float _fYDgre;

     

    void Awake()

        {

            // cache

            _tfmThis = transform;

     

            _fCurtDist = Vector3.Distance(_tfmThis.position, _tfmRotAxis.position );

            _fTarDist = _fCurtDist;

     

            // 在世界坐标系之下。计算摄像机本地坐标系各坐标轴

            // 与世界坐标系各坐标轴的夹角

            _fXDgre = Vector3.Angle(Vector3.right, _tfmThis.right );// X轴夹角

            _fYDgre = Vector3.Angle(Vector3.up, _tfmThis.up );// Y轴夹角

        }

     

        void LateUpdate()

        {

            // 检測鼠标右键按下

            if ( Input.GetMouseButton( 1 ) ) {

     

                // 计算当前的轴向夹角

                _fXDgre += Input.GetAxis("Mouse X" ) * _fXSpe;

                _fYDgre -= Input.GetAxis("Mouse Y" ) * _fYSpe;

                // 对夹角进行限位处理

                _fXDgre = Mathf.Clamp(_fXDgre, _fMinLimitX, _fMaxLimitX );

                _fYDgre = Mathf.Clamp(_fYDgre, _fMinLimitY, _fMaxLimitY );

                // 计算目标朝向(方位)

                _quaTarRtn = Quaternion.Euler( _fYDgre, _fXDgre, 0 );

                // 插值运算

                _tfmThis.rotation = Quaternion.Lerp( _tfmThis.rotation, _quaTarRtn,_fZoomDmp *Time.deltaTime );

            }

     

            ScrollWheelCtrl();

        }


        ///<summary>

        ///鼠标滚轮控制视野的缩放

        ///</summary>

        private void ScrollWheelCtrl()

        {

            _fTarDist -= Input.GetAxis("Mouse ScrollWheel" ) * _fZoomRate*Time.deltaTime;

     

            _fTarDist = Mathf.Clamp(_fTarDist, _fMinDist, _fMaxDist );

     

            _fCurtDist = Mathf.Lerp(_fCurtDist, _fTarDist, _fZoomDmp *Time.deltaTime);

     

            _tfmThis.position =_tfmRotAxis.position - ( _tfmThis.rotation *Vector3.forward* _fCurtDist + _vec3TarOffset );

        }

  • 相关阅读:
    别做操之过急的”无效将军”,做实实在在的”日拱一卒”
    大话三种个性化推荐,你喜欢哪一种?
    程序员的厚德载物(上)
    腾讯或联姻优酷,微信嫁女模式引发互联网通婚潮流
    [PHP知识点乱炖]四、全局变量——小偷从良记
    小谈程序员创业者的”劣根性”
    腾讯程序员一年3亿代码意味着什么?
    腾讯和京东做了连襟:一个枪和弹合作的故事
    程序员初学者如何自学编程另类版
    从软件公司的企业文化浅谈什么是管理能力
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7389020.html
Copyright © 2011-2022 走看看