u3D开发学习之路--鼠标控制摄像机旋转

2016.8.29更新

--------------------------------------------------------------------------------------------------------------------

using UnityEngine;
using System.Collections;

/// 
///  按下鼠标右键,摄像机自转
/// 
public class DoRotation : MonoBehaviour
{
    public float rotateSpeed = 10;

    /// 
    /// 与y轴最小夹角
    /// 
    public float yAxisMinAngle = 60;

    /// 
    /// 与y轴最大夹角
    /// 
    public float yAxisMaxAngle = 330;
     
    private void FixedUpdate()
    {
        float x = Input.GetAxis("Mouse X");
        float y = Input.GetAxis("Mouse Y");

        if (Input.GetMouseButton(1) && (x != 0 || y != 0))
        { 
            RotateView(x, y); 
        }
    }

    private void RotateView(float x, float y)
    {
        x *= rotateSpeed;
        y *= rotateSpeed;
         
        //大于330     小于60
        if (this.transform.eulerAngles.x - y > yAxisMaxAngle || this.transform.eulerAngles.x - y < yAxisMinAngle)
        { 
            this.transform.Rotate(0, x, 0, Space.World);
            this.transform.Rotate(-y, 0, 0);
        }
    }  
}
using UnityEngine;
using System.Collections;

/// 
///  按下鼠标左键,摄像机围绕目标旋转
/// 
public class DoRotateAround : MonoBehaviour
{
    //当前围绕的目标
    public Transform targetTf;

    public float rotateSpeed = 10;
       
    /// 
    /// 与y轴最大夹角
    /// 
    public float yMaxAngle = 160;

    /// 
    /// 与y轴最小夹角
    /// 
    public float yMinAngle = 120;

    private void RotateAround(float x, float y)
    {
        this.transform.RotateAround
            (targetTf.position, Vector3.up, x * rotateSpeed);

        LimitAxisY(ref y);

        this.transform.RotateAround
            (targetTf.position, this.transform.right, -y);
    }

    private void LimitAxisY(ref float y)
    {
        y *= rotateSpeed;
        //计算当前摄像机Z轴与世界Y轴夹角
        float angle = Vector3.Angle(this.transform.forward, Vector3.up);
        if (angle < yMinAngle && y > 0 || angle > yMaxAngle && y < 0)
            y = 0; 
    }

    private void LookAtTarget()
    {
        this.transform.LookAt(targetTf);
    }

    private void Start()
    {
        if (targetTf == null)
            targetTf = new GameObject("Target").transform; 

        LookAtTarget(); 
    }

    private void FixedUpdate()
    {
        float x = Input.GetAxis("Mouse X");
        float y = Input.GetAxis("Mouse Y");

        if (Input.GetMouseButton(0) && (x != 0 || y != 0))
            RotateAround(x , y ); 
    }
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

先说说编程习惯的问题,在写代码的时候我们应该尽量让别人对自己的代码的来龙去脉一目了然。我在最开始写代码的时候,只是一味的往上面写,无论是从可读性还是对内存的分配空间的利用率都很差,如果代码出现问题根本不愿意再回头检查,因为实在是太乱了。但是通过这两个星期不断的阅读老师的代码,我逐渐的开始规范自己的代码,让其更加具有可读性,高聚类,低耦合。

using UnityEngine;
using System.Collections;
/// 
/// 通过鼠标左键可以使摄像机绕物体旋转
/// 鼠标右键可以是摄像机自身旋转
/// 鼠标滚轮可以对摄像机进行缩放
/// 
public class ControlByMouse : MonoBehaviour
{
    //自身旋转的速度
    public float rotateSpeed = 10;
    //缩放速度
    public float fieldOfViewSpeed = 10;
    //绕物体旋转的速度
    public float rotateLookForwardSpeed = 10;
    //声明水平、垂直位移
    float horizontal, vertical;
    //声明摄像机旋转的对象
    public Transform targetTF;
    //声明摄像机
    Camera camera;
    void Start()
    {
        //初始化摄像机
        camera = this.transform.GetComponent();
    }
    void Update()
    {
        RotateByMouse();
        ChangeFieldOfView();
        RotateAndLookForward();
    }
    //获取水平以及垂直位移
    private void GetMouseXY()
    {
        horizontal = Input.GetAxis("Mouse X");
        vertical = Input.GetAxis("Mouse Y");
    }
    //缩放方法
    private void ChangeFieldOfView()
    {
        float value = Input.GetAxis("Mouse ScrollWheel");
        if (value > 0f && camera.fieldOfView > 70 || value < 0f && camera.fieldOfView < 40)
        {
            value = 0f;
        }
        camera.fieldOfView += value * fieldOfViewSpeed * Time.deltaTime;
    }
    //自身旋转方法
    private void RotateByMouse()
    {
        if (Input.GetMouseButton(1))
        {
            GetMouseXY();
            this.transform.Rotate(-vertical * Time.deltaTime * rotateSpeed, horizontal * Time.deltaTime * rotateSpeed, 0);
        }
    }
    //绕物体旋转方法
    private void RotateAndLookForward()
    {
        if (Input.GetMouseButton(0))
        {
            GetMouseXY();
            this.transform.RotateAround(targetTF.position, Vector3.up, horizontal * Time.deltaTime * rotateLookForwardSpeed);
            this.transform.RotateAround(targetTF.position, Vector3.right, -vertical * Time.deltaTime * rotateLookForwardSpeed);

        }
    }
}

代码比较简单,没有什么特别难懂的地方,只不过在绕X轴旋转的时候,我们需要把vertical的值设为负值,原因是,当摄像机向上看的时候,其实摄像机是绕X轴向下移动的,同理,当摄像机向下看的时候,是绕X轴向上移动的。功能还有一些没有完善,比如自身旋转的时候,在绕X轴的时候应该设置一个角度的范围,避免“翻跟头”。

你可能感兴趣的:(Unity3D)