摄像机控制,左键旋转,右键平移,滚轮缩进远离

公司准备做二期的项目,自己给项目的一些需求提前先做一些记录,自己拿了一期项目(别人写的)的源代码看了一下,对于一期项目摄像机控制并不是满意,然后自己对比一下某网站操作方式做了修改,代码基本参考网上的代码。主要功能就是左键旋转,右键平移,滚轮缩进远离。

参考一:https://blog.csdn.net/sinat_27456831/article/details/49366947

这里主要是修改滚轮缩进远离其它代码基本没有改动。

参考二:https://blog.csdn.net/sinat_20559947/article/details/46437979

这里代码右键上下拖动并不是上下视角主要是坐标y没有变动,变动的是左边z,修改组合之后就成了完整的操作方式。

基本上代码的注释都非常详尽,其他细节的代码方法请查阅api

具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class mousedrag : MonoBehaviour 
{

    //旋转速度,需要调试
    public float xSpeed = 130.0f;
    public float ySpeed = 130.0f;
    //限制旋转角度,物体绕x轴旋转限制,不能上下颠倒。
    public float yMinLimit = -30;
    public float yMaxLimit = 30;
    //物体的旋转角度
    public float x = 0.0f;
    public float y = 0.0f;
    // 设置相机移动速度 
    public float moveSpeed = 10; 
    void Start()
    {
        //初始化旋转角度,记录开始时物体的旋转角度。
        Vector3 angels = transform.eulerAngles;
        x = angels.y;
        y = angels.x;
        //
    }
    void Update()
    {
        // 当按住鼠标右键的时候  
        if (Input.GetMouseButton(1))
        {
            // 获取鼠标的x和y的值,乘以速度和Time.deltaTime是因为这个可以是运动起来更平滑  
            float h = Input.GetAxis("Mouse X") * -moveSpeed * Time.deltaTime;
            float v = Input.GetAxis("Mouse Y") * -moveSpeed * Time.deltaTime;
            // 设置当前摄像机移动,y轴并不改变  
            // 需要摄像机按照世界坐标移动,而不是按照它自身的坐标移动,所以加上Spance.World
            this.transform.Translate(h, v, 0, Space.World);
        }

        if (Input.GetMouseButton(0))
        {
            //鼠标沿x轴的移动乘以系数当作物体绕y轴的旋转角度。
            //鼠标沿y轴的移动乘以系数当作物体绕x轴的旋转角度。
            x += Input.GetAxis("Mouse X") * xSpeed * Time.deltaTime;
            y += Input.GetAxis("Mouse Y") * ySpeed * Time.deltaTime;
        }
        Camera.main.fieldOfView = Camera.main.fieldOfView - Input.GetAxis("Mouse ScrollWheel") * 20;
    }
    void LateUpdate()
    {
        //限制绕x轴的移动。
        y = Mathf.Clamp(y, yMinLimit, yMaxLimit);
        Quaternion rotation = Quaternion.Euler(y, -x, 0);
        transform.rotation = rotation;
    }
}

脚本挂在摄像机上,运行一下发现ok,调一下xspeed数值完成。暂时不考虑一些最大范围和最小范围的限制就这样。

 

编辑:

因为客户觉得之前摄像机控制不好用,所以做了一堆修改,不使用上下左右键移动以及添加旋转摄像机功能,主要代码如下:

 /// <summary>
    /// 滚轮控制摄像机缩放
    /// </summary>
    private void WheelContrl()
    {
        float distance = 0;
        distance = Input.GetAxis("Mouse ScrollWheel") * moveSpeed_s;//获取鼠标中建响应

        transform.position = transform.position + transform.rotation *new Vector3(0, 0, distance);

        //        //滚轮控制  
        //        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        //        {
        //            //控制的范围自行调整
        //            if (Camera.main.fieldOfView <= 100)
        //            {
        //                Camera.main.fieldOfView += 2;
        //            }

        //            if (Camera.main.orthographicSize <= 20)
        //            {
        //                Camera.main.orthographicSize += 0.5F;
        //            }
        //        }
        //        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        //        {
        //            if (Camera.main.fieldOfView > 20
        //)
        //            {
        //                Camera.main.fieldOfView -= 2;
        //            }
        //            if (Camera.main.orthographicSize >= 1)
        //            {
        //                Camera.main.orthographicSize -= 0.5F;
        //            }
        //        }


    }


    void RotateCamera()
    {
        //鼠标左键按下状态启用旋转摄像机
        if (Input.GetMouseButtonDown(0))
        {
            isRotate = true;
        }

        //鼠标左键抬起状态停止旋转摄像机
        if (Input.GetMouseButtonUp(0))
        {
            isRotate = false;
        }
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            if (isRotate)
            {
                //x 和 y 是绝对值 相对于世界坐标没有转动的位置的最终转动位置

                //鼠标的上下移动 移动的Y值 在三维中相当于沿X轴转动
                y -= Input.GetAxis("Mouse Y") * moveSpeed_y * Time.deltaTime;
                //上下需要限定范围 在完全俯视 和 完全仰视之间
                //去掉该限制的话可以使摄像机倒置
                y = Mathf.Clamp(y, yMinLimit, yMaxLimit);


                //鼠标的左右移动 移动的X值 在三维中相当于沿Y轴转动
                //左右是允许360度旋转的 不需要限制到最大最小范围
                x += Input.GetAxis("Mouse X") * moveSpeed_x * Time.deltaTime;

                //Quaternion rotation = Quaternion.Euler(y, x, 0);
                //transform.rotation = rotation;

                //和上面2句等价
                transform.eulerAngles = new Vector3(y, x, 0);
            }
        }
           
    }

因为放大缩小客户一直觉得视角变形了,所以做了修改,完整代码包含之前的功能,完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class CameraContrl : MonoBehaviour
{
    /// <summary>
    /// 摄像机X轴 Z轴的坐标的临界点
    /// </summary>
    public float Z_min;
    public float Z_max;
    public float X_min;
    public float X_max;
    public float Y_min;
    public float Y_max;

    //主摄像机起始坐标
    private Vector3 StartPos;

    //主摄像机缩放参数
    private float StartFieldOfView;

    private Vector3 StartRotation;
    //[SerializeField]
    //private Slider SpeedSlider;

    // 设置相机移动速度 ,测试最大速度30
    public float moveSpeed_x;//X轴的移动速度
    public float moveSpeed_y;//Y轴的移动速度
    public float moveSpeed_s;//鼠标滑动到边界摄像机的移动速度

    public float yMinLimit = -90f; //上下旋转摄像机的最小角度限制
    public float yMaxLimit = 90f;  //上下旋转摄像机的最大角度限制

    //是否旋转镜头 鼠标右键按下时启用
    private bool isRotate;
    //左右旋转的角度 相对世界原始位置 非transform初始位置(沿三维Y轴)
    private float x;
    //上下旋转的角度 相对世界原始位置 非transform初始位置(沿三维X轴)
    private float y;


    public float Min = 0.05f;

    private void Awake()
    {
        //SpeedSlider = GameObject.Find("SettingPanel/SpeedSlider").GetComponent<Slider>();    
        StartPos = Camera.main.transform.position;
        StartFieldOfView = Camera.main.fieldOfView;
        StartRotation = Camera.main.transform.eulerAngles;

        Vector3 angles = transform.eulerAngles;
        //鼠标的左右移动 在三维中相当于沿Y轴转动
        x = angles.y;
        //鼠标的上下移动 在三维中相当于沿X轴转动
        y = angles.x;
       
    }

   
	
	// Update is called once per frame
	void LateUpdate() 
	{

        Boundary();

        WheelContrl();

        RotateCamera();

        DragScreen();

        //CodeControl();

        //MouseControl();

        if (Input.GetKeyDown(KeyCode.F5))
        {
            ResetPos();
        }

    }

    /// <summary>
    /// 摄像机移动边界设定
    /// </summary>
    public void Boundary()
    {
        Vector3 pos = Camera.main.transform.localPosition;
        Camera.main.transform.localPosition = new Vector3(Mathf.Clamp(pos.x, X_min, X_max), Mathf.Clamp(pos.y, Y_min, Y_max), Mathf.Clamp(pos.z, Z_min, Z_max));
    }
    /// <summary>
    /// 重置摄像机位置
    /// </summary>
    private void ResetPos()
    {
        Camera.main.transform.position = StartPos;
        Camera.main.transform.eulerAngles = StartRotation;
        Camera.main.fieldOfView = StartFieldOfView;
    }

    /// <summary>
    /// 滚轮控制摄像机缩放
    /// </summary>
    private void WheelContrl()
    {
        float distance = 0;
        distance = Input.GetAxis("Mouse ScrollWheel") * moveSpeed_s;//获取鼠标中建响应

        transform.position = transform.position + transform.rotation *new Vector3(0, 0, distance);

        //        //滚轮控制  
        //        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        //        {
        //            //控制的范围自行调整
        //            if (Camera.main.fieldOfView <= 100)
        //            {
        //                Camera.main.fieldOfView += 2;
        //            }

        //            if (Camera.main.orthographicSize <= 20)
        //            {
        //                Camera.main.orthographicSize += 0.5F;
        //            }
        //        }
        //        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        //        {
        //            if (Camera.main.fieldOfView > 20
        //)
        //            {
        //                Camera.main.fieldOfView -= 2;
        //            }
        //            if (Camera.main.orthographicSize >= 1)
        //            {
        //                Camera.main.orthographicSize -= 0.5F;
        //            }
        //        }


    }


    void RotateCamera()
    {
        //鼠标左键按下状态启用旋转摄像机
        if (Input.GetMouseButtonDown(0))
        {
            isRotate = true;
        }

        //鼠标左键抬起状态停止旋转摄像机
        if (Input.GetMouseButtonUp(0))
        {
            isRotate = false;
        }
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            if (isRotate)
            {
                //x 和 y 是绝对值 相对于世界坐标没有转动的位置的最终转动位置

                //鼠标的上下移动 移动的Y值 在三维中相当于沿X轴转动
                y -= Input.GetAxis("Mouse Y") * moveSpeed_y * Time.deltaTime;
                //上下需要限定范围 在完全俯视 和 完全仰视之间
                //去掉该限制的话可以使摄像机倒置
                y = Mathf.Clamp(y, yMinLimit, yMaxLimit);


                //鼠标的左右移动 移动的X值 在三维中相当于沿Y轴转动
                //左右是允许360度旋转的 不需要限制到最大最小范围
                x += Input.GetAxis("Mouse X") * moveSpeed_x * Time.deltaTime;

                //Quaternion rotation = Quaternion.Euler(y, x, 0);
                //transform.rotation = rotation;

                //和上面2句等价
                transform.eulerAngles = new Vector3(y, x, 0);
            }
        }
           
    }


    /// <summary>
    /// 鼠标右键拖拽移动上下左右视角
    /// </summary>
    private void DragScreen()
    {
        // 当按住鼠标右键的时候  
        if (Input.GetMouseButton(1))
        {
            // 获取鼠标的x和y的值,乘以速度和Time.deltaTime是因为这个可以是运动起来更平滑  
            float h = Input.GetAxis("Mouse X") * moveSpeed_s * Time.deltaTime;
            float v = Input.GetAxis("Mouse Y") * moveSpeed_s * Time.deltaTime;
            // 设置当前摄像机移动,y轴并不改变  
            // 需要摄像机按照世界坐标移动,而不是按照它自身的坐标移动,所以加上Spance.World
            Camera.main.transform.Translate(-h, 0, -v, Space.World);

        }
    }

    /// <summary>
    /// 实时更新摄像机速度值
    /// </summary>
    public void GetSpeed(float value)
    {
        //moveSpeed_x = value*50;

    }

    /// <summary>
    /// 按键控制摄像机移动
    /// </summary>
    private void CodeControl()
    {
        //float h = Mathf.Clamp()
        float h = Input.GetAxisRaw("Horizontal") * moveSpeed_x * Time.deltaTime;
        float v = Input.GetAxisRaw("Vertical") * moveSpeed_y * Time.deltaTime;

            Camera.main.transform.Translate(h, 0, v, Space.World);

    }

    /// <summary>
    /// 鼠标放在屏幕边缘移动摄像机
    /// </summary>
    private void MouseControl()
    {
        Vector3 v1 = Camera.main.ScreenToViewportPoint(Input.mousePosition);
        //移到ui上不触发
        if (EventSystem.current.IsPointerOverGameObject())
        {
            return;
        }
        //范围限制
        if (v1.x > 1 + Min || v1.x < -Min || v1.y > 1 + Min || v1.y < -Min) return;

        if (v1.x < Min)//鼠标停靠在左边
        {
            transform.Translate(Vector3.left * moveSpeed_s * Time.deltaTime, Space.World);
        }
        if (v1.x > 1 - Min)//鼠标停靠在右边
        {
            transform.Translate(Vector3.right * moveSpeed_s * Time.deltaTime, Space.World);
        }
        if (v1.y < Min)//鼠标停靠在下边
        {
            transform.Translate(Vector3.back * moveSpeed_s * Time.deltaTime, Space.World);
        }
        if (v1.y > 1 - Min)//鼠标停靠在上边
        {
            transform.Translate(Vector3.forward * moveSpeed_s * Time.deltaTime, Space.World);
        }
       
    }

}

今天测试摄像机发现旋转之后位置移动就错误了重新做了修改,完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class CameraContrl : MonoBehaviour
{
    /// <summary>
    /// 摄像机X轴 Z轴的坐标的临界点
    /// </summary>
    public float Z_min;
    public float Z_max;
    public float X_min;
    public float X_max;
    public float Y_min;
    public float Y_max;

    //主摄像机起始坐标
    private Vector3 StartPos;

    //主摄像机缩放参数
    private float StartFieldOfView;

    private Vector3 StartRotation;

    private Vector3 cameraPos;
    //[SerializeField]
    //private Slider SpeedSlider;

    // 设置相机移动速度 ,测试最大速度30
    public float moveSpeed_x;//X轴的移动速度
    public float moveSpeed_y;//Y轴的移动速度
    public float moveSpeed_s;//鼠标滑动到边界摄像机的移动速度

    public float yMinLimit = -90f; //上下旋转摄像机的最小角度限制
    public float yMaxLimit = 90f;  //上下旋转摄像机的最大角度限制

    //是否旋转镜头 鼠标右键按下时启用
    private bool isRotate;
    //左右旋转的角度 相对世界原始位置 非transform初始位置(沿三维Y轴)
    private float x;
    //上下旋转的角度 相对世界原始位置 非transform初始位置(沿三维X轴)
    private float y;


    public float Min = 0.05f;

    private void Awake()
    {
        //SpeedSlider = GameObject.Find("SettingPanel/SpeedSlider").GetComponent<Slider>();    
        StartPos = Camera.main.transform.position;
        cameraPos = Camera.main.transform.position;
        StartFieldOfView = Camera.main.fieldOfView;
        StartRotation = Camera.main.transform.eulerAngles;

        Vector3 angles = transform.eulerAngles;
        //鼠标的左右移动 在三维中相当于沿Y轴转动
        x = angles.y;
        //鼠标的上下移动 在三维中相当于沿X轴转动
        y = angles.x;
       
    }

   
	
	// Update is called once per frame
	void LateUpdate() 
	{
        if (EventSystem.current.IsPointerOverGameObject()) return;
        Boundary();

        WheelContrl();

        RotateCamera();

        DragScreen();
        transform.position = cameraPos;
        //CodeControl();

        //MouseControl();

        if (Input.GetKeyDown(KeyCode.F5))
        {
            ResetPos();
        }

    }

    /// <summary>
    /// 摄像机移动边界设定
    /// </summary>
    public void Boundary()
    {
        Vector3 pos = Camera.main.transform.localPosition;
        cameraPos = new Vector3(Mathf.Clamp(pos.x, X_min, X_max), Mathf.Clamp(pos.y, Y_min, Y_max), Mathf.Clamp(pos.z, Z_min, Z_max));
    }
    /// <summary>
    /// 重置摄像机位置
    /// </summary>
    private void ResetPos()
    {
        Camera.main.transform.position = StartPos;
        Camera.main.transform.eulerAngles = StartRotation;
        Camera.main.fieldOfView = StartFieldOfView;
    }

    /// <summary>
    /// 滚轮控制摄像机缩放
    /// </summary>
    private void WheelContrl()
    {
        float distance = 0;
        distance = Input.GetAxis("Mouse ScrollWheel") * moveSpeed_s;//获取鼠标中键响应

        transform.position = transform.position + transform.rotation *new Vector3(0, 0, distance);

        //滚动鼠标滑轮缩放摄像机
        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        {
            if (cameraPos.y < Y_min)
                return;
            Vector3 moveDirectionZ = transform.forward;
            cameraPos += moveDirectionZ * moveSpeed_s;
        }
        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
            if (cameraPos.y > Y_max)
                return;
            Vector3 moveDirectionZ = -transform.forward;
            cameraPos += moveDirectionZ * moveSpeed_s;
        }



        //        //滚轮控制  
        //        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        //        {
        //            //控制的范围自行调整
        //            if (Camera.main.fieldOfView <= 100)
        //            {
        //                Camera.main.fieldOfView += 2;
        //            }

        //            if (Camera.main.orthographicSize <= 20)
        //            {
        //                Camera.main.orthographicSize += 0.5F;
        //            }
        //        }
        //        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        //        {
        //            if (Camera.main.fieldOfView > 20
        //)
        //            {
        //                Camera.main.fieldOfView -= 2;
        //            }
        //            if (Camera.main.orthographicSize >= 1)
        //            {
        //                Camera.main.orthographicSize -= 0.5F;
        //            }
        //        }


    }


    void RotateCamera()
    {
        //鼠标左键按下状态启用旋转摄像机
        if (Input.GetMouseButtonDown(0))
        {
            isRotate = true;
        }

        //鼠标左键抬起状态停止旋转摄像机
        if (Input.GetMouseButtonUp(0))
        {
            isRotate = false;
        }
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            if (isRotate)
            {
                //x 和 y 是绝对值 相对于世界坐标没有转动的位置的最终转动位置

                //鼠标的上下移动 移动的Y值 在三维中相当于沿X轴转动
                y -= Input.GetAxis("Mouse Y") * moveSpeed_y * Time.deltaTime;
                //上下需要限定范围 在完全俯视 和 完全仰视之间
                //去掉该限制的话可以使摄像机倒置
                y = Mathf.Clamp(y, yMinLimit, yMaxLimit);


                //鼠标的左右移动 移动的X值 在三维中相当于沿Y轴转动
                //左右是允许360度旋转的 不需要限制到最大最小范围
                x += Input.GetAxis("Mouse X") * moveSpeed_x * Time.deltaTime;

                //Quaternion rotation = Quaternion.Euler(y, x, 0);
                //transform.rotation = rotation;

                //和上面2句等价
                transform.eulerAngles = new Vector3(y, x, 0);
            }
        }
           
    }


    /// <summary>
    /// 鼠标右键拖拽移动上下左右视角
    /// </summary>
    private void DragScreen()
    {
        // 当按住鼠标右键的时候  
        if (Input.GetMouseButton(1))
        {
             获取鼠标的x和y的值,乘以速度和Time.deltaTime是因为这个可以是运动起来更平滑  
            //float h = Input.GetAxis("Mouse X") * moveSpeed_s * Time.deltaTime;
            //float v = Input.GetAxis("Mouse Y") * moveSpeed_s * Time.deltaTime;
             设置当前摄像机移动,y轴并不改变  
             需要摄像机按照世界坐标移动,而不是按照它自身的坐标移动,所以加上Spance.World
            TODO 方向判断
            //Camera.main.transform.Translate(-h, 0, -v, Space.World);


            //第一种方法按下WS、AD,Input.GetAxis()会返回1或-1
            float moveZ = -Input.GetAxis("Mouse Y");
            Vector3 moveDirectionZ = transform.forward;
            moveDirectionZ.y = 0;
            cameraPos += moveDirectionZ * moveZ * moveSpeed_s;
            float moveX = -Input.GetAxis("Mouse X");
            Vector3 moveDirectionX = transform.right;
            moveDirectionZ.y = 0;
            cameraPos += moveDirectionX * moveX * moveSpeed_s;

            
        }
        
    }

    /// <summary>
    /// 实时更新摄像机速度值
    /// </summary>
    public void GetSpeed(float value)
    {
        //moveSpeed_x = value*50;

    }

    /// <summary>
    /// 按键控制摄像机移动
    /// </summary>
    private void CodeControl()
    {
        //float h = Mathf.Clamp()
        float h = Input.GetAxisRaw("Horizontal") * moveSpeed_x * Time.deltaTime;
        float v = Input.GetAxisRaw("Vertical") * moveSpeed_y * Time.deltaTime;

            Camera.main.transform.Translate(h, 0, v, Space.World);

    }

    /// <summary>
    /// 鼠标放在屏幕边缘移动摄像机
    /// </summary>
    private void MouseControl()
    {
        Vector3 v1 = Camera.main.ScreenToViewportPoint(Input.mousePosition);
        //移到ui上不触发
        if (EventSystem.current.IsPointerOverGameObject())
        {
            return;
        }
        //范围限制
        if (v1.x > 1 + Min || v1.x < -Min || v1.y > 1 + Min || v1.y < -Min) return;

        if (v1.x < Min)//鼠标停靠在左边
        {
            transform.Translate(Vector3.left * moveSpeed_s * Time.deltaTime, Space.World);
        }
        if (v1.x > 1 - Min)//鼠标停靠在右边
        {
            transform.Translate(Vector3.right * moveSpeed_s * Time.deltaTime, Space.World);
        }
        if (v1.y < Min)//鼠标停靠在下边
        {
            transform.Translate(Vector3.back * moveSpeed_s * Time.deltaTime, Space.World);
        }
        if (v1.y > 1 - Min)//鼠标停靠在上边
        {
            transform.Translate(Vector3.forward * moveSpeed_s * Time.deltaTime, Space.World);
        }
       
    }

}

这功能应该是最后一次修改了,主要修改速度和边界的数值就可以使用了。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值