Unity教程合集unity3D技术分享

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

2016-09-08  本文已影响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);
    }



、、、、
上一篇下一篇

猜你喜欢

热点阅读