Unity摄像机控制

Unity摄像机控制:

控制摄像机移动,旋转,缩放,跳跃;有视野限制,且摄像机高度越高运动幅度越大。

视野缩放:通过向前滚动鼠标滑轮可拉近视野,向后滚动鼠标滑轮可拉远视野。

视野移动:按住鼠标左键不放时,移动鼠标可控制视野向鼠标图标移动方向平滑移动,即视野可在上、下、左、右四个方向上平移。

视野旋转:按住鼠标右键不放时,移动鼠标可控制视野向鼠标图标移动方向旋转。垂直方向旋转范围为-90度到90度,水平方向无限制,可360度旋转。

视野跳跃:双击鼠标左键可控制视野向鼠标图标方向跳跃一段距离;双击鼠标右键可控制视野向后跳跃一段距离。

视野限制:视野不能移动到限制的长方体空间外。
代码如下:

///文件名:CameraController.cs

///功能:摄像机自由控制类
///摘要:
///创建日期:2016.1.13
///修改日志:

using UnityEngine;

public class CameraController : MonoBehaviour
{
    private static Transform cameraSelf;

    public float scrollSpeed;
    public float moveSpeed;
    public float rotateSpeed    = 2;        
    public float moveSpeedMin   = 0.5f;
    public float moveSpeedMax   = 500f;
    public float scrollSpeedMax = 30000;
    public float scrollSpeedMin = 50f;
    public float heightMax      = 15000f;
    public float heightMin      = 20f;
    public float cameraXMin     = 2000f;
    public float cameraXMax     = 18000f;
    public float cameraZMin     = 3000f;
    public float cameraZMax     = 27000f;

    public  float jumpHeightMin;
    public  float jumpSpeedMax;
    public  float jumpSpeedMin;
    private float jumpDistance;

    private float mouseDownDuration = 0.3f;
    private float lastLeftDownTime  = -1;
    private float lastrightDownTime = -1;

    private float rotate_X;
    private float rotate_Y;
    private float move_X;
    private float move_Y;

    Ray ray;
    RaycastHit hitInfo;

    void Start()
    {
        cameraSelf = transform;
    }   
   
    void LateUpdate()
    {        
        CameraJump();
        CameraZoom();
        CameraRotate();
        CameraMove();
        CameraLimit();
    }   

    /// <summary>
    /// 滑轮控制视野缩放
    /// </summary>
    void CameraZoom()
    {
        float scrollAxis = Input.GetAxis("Mouse ScrollWheel"); 
        if (scrollAxis != 0)
        {
            scrollSpeed = (scrollSpeedMin + (cameraSelf.position.y - heightMin)
                / (heightMax - heightMin) * (scrollSpeedMax - scrollSpeedMin));


            scrollSpeed = Mathf.Clamp(scrollSpeed, scrollSpeedMin, scrollSpeedMax);
            Vector3 targetPoint = cameraSelf.position + cameraSelf.forward
                * scrollAxis * scrollSpeed;


            cameraSelf.position = Vector3.Lerp(cameraSelf.position, targetPoint, Time.deltaTime);
        }
    }


    /// <summary>
    /// 鼠标左键控制移动
    /// </summary>    
    void CameraMove()
    {      
        if (Input.GetMouseButton(0))
        {
            moveSpeed = moveSpeedMin + (cameraSelf.position.y - heightMin)
                / (heightMax - heightMin) * (moveSpeedMax - moveSpeedMin);


            moveSpeed = Mathf.Clamp(moveSpeed, moveSpeedMin, moveSpeedMax);
            move_Y    = Input.GetAxis("Mouse Y") * moveSpeed;
            move_X    = Input.GetAxis("Mouse X") * moveSpeed;
            cameraSelf.position += -cameraSelf.right * move_X - cameraSelf.up * move_Y;
        }
    }
   

    /// <summary>
    /// 鼠标右键控制旋转
    /// </summary>
    void CameraRotate()
    {      
        if (Input.GetMouseButton(1))
        {
            rotate_X = cameraSelf.eulerAngles.x;
            rotate_Y = cameraSelf.eulerAngles.y;


            rotate_X -= Input.GetAxis("Mouse Y") * rotateSpeed;
            rotate_Y += Input.GetAxis("Mouse X") * rotateSpeed;
            rotate_X  = ClampAngle(rotate_X, 1, 89);
            rotate_Y  = ClampAngle(rotate_Y, -360, 360);
            cameraSelf.rotation = Quaternion.Euler(rotate_X, rotate_Y, 0);
        }
    } 
  

    /// <summary>
    /// 规划角度
    /// </summary>
    /// <param name="angle">实际角度</param>
    /// <param name="minAngle">最小角度</param>
    /// <param name="maxAgnle">最大角度</param>
    /// <returns>限制范围内的角度</returns>
    float ClampAngle(float angle, float minAngle, float maxAgnle)
    {
        if (angle <= -360)
            angle += 360;
        if (angle >= 360)
            angle -= 360;


        return Mathf.Clamp(angle, minAngle, maxAgnle);
    }

    ///视野跳跃
    void CameraJump()
    {

         //双左键击视野向鼠标点击方向跳跃
        if (Input.GetMouseButtonDown(0))
        {
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Physics.Raycast(ray, out hitInfo);
           
            if (Time.time - lastLeftDownTime < mouseDownDuration)
            {
                jumpDistance = (jumpSpeedMin + (cameraSelf.position.y - jumpHeightMin) /
                                               (heightMax - jumpHeightMin) * (jumpSpeedMax - jumpSpeedMin));
                cameraSelf.position += ray.direction * jumpDistance;
            }
            lastLeftDownTime = Time.time;            
        }

        //双击右键视野向后退
        if (Input.GetMouseButtonDown(1))
        {                

            if (Time.time - lastrightDownTime < mouseDownDuration)
            {
                jumpDistance = (jumpSpeedMin + (cameraSelf.position.y - jumpHeightMin) /
                                               (heightMax - jumpHeightMin) * (jumpSpeedMax - jumpSpeedMin));
                cameraSelf.position -= cameraSelf.forward * jumpDistance;
            }
            lastrightDownTime = Time.time;
        }
    }

    /// <summary>
    /// 摄像限制
    /// </summary>
    void CameraLimit()
    {
        Vector3 vec = cameraSelf.position;
        vec.x = Mathf.Clamp(vec.x, cameraXMin, cameraXMax);
        vec.y = Mathf.Clamp(vec.y, heightMin, heightMax);
        vec.z = Mathf.Clamp(vec.z, cameraZMin, cameraZMax);
        cameraSelf.position = vec;
    }
}

在实际使用过程中可能需要实现在点击在界面UI上时不改变视野,这时可使用EventSystem.current.IsPointerOverGameObject(),通过此函数可判断是否点击到UI上,若点击到UI上则返回true,未点击到UI上则返回false。

     
          

猜你喜欢

转载自blog.csdn.net/StudyHard_luozhongxu/article/details/75505140