unity 鼠标移动 缩放,旋转

本文介绍了一个Unity脚本,用于实现3D和2D视角下的相机控制,并加入了防止UI穿透的功能。通过检测鼠标滚轮操作调整视野角度,同时允许在鼠标右键按下时旋转相机。还提供了一个方法来检测鼠标是否悬停在UI元素上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2018-11-25修改:加入防止UI穿透,如果相机有PhysicsRaycaster组件,考虑检测到UI是否向下传递给3D物体
这时使用 EventSystem.current.IsPointerOverGameObject()的判断 不合适
2018-11-23修改:加入相机2D视角 和3D视角控制


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
[System.Serializable]
public class LimitPoint
{
    public Transform left;
    public Transform right;
    public Transform up;
    public Transform down;
}
public class MoustControl : MonoBehaviour
{
    public float minFov = 1f;
    public float maxFov = 100f;
    public float sensitivity = 15f;



    enum RotationAxes { MouseXAndY, MouseX, MouseY }
    RotationAxes axes = RotationAxes.MouseXAndY;
    //@HideInInspector
    float sensitivityX = 1.5f;
    //@HideInInspector
    float sensitivityY = 1.5f;
    //private float minimumX = -360; 原文有此行但并未使用此变量
    //private float maximumX = 360; 同上
    float minimumY =-7;
    float maximumY = 70;
   private float rotationY = 0;

    private float moveSpeed=0.3f;
    private Vector3 lastPos;

    private float fixedY = 0;

    public bool is3D=false;
    private bool isHoverUI;
    private void Awake()
    {
        fixedY = transform.position.y;

    }
    void Update()
    {
        if (is3D)
        {
            float fov = Camera.main.fieldOfView;
            fov += -Input.GetAxis("Mouse ScrollWheel") * sensitivity;
            fov = Mathf.Clamp(fov, minFov, maxFov);
            Camera.main.fieldOfView = fov;

            //相机旋转
            if (Input.GetMouseButton(1))
            {

                if (axes == RotationAxes.MouseXAndY)
                {
                    float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
                    rotationY = transform.localEulerAngles.x + Input.GetAxis("Mouse Y") * sensitivityY;
                    rotationY = Mathf.Clamp(Mathf.Abs(rotationY), minimumY, maximumY);
                    transform.localEulerAngles = new Vector3(rotationY, rotationX, 0);
                }
                else if (axes == RotationAxes.MouseX)
                {
                    transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
                }
                else
                {
                    rotationY = transform.localEulerAngles.x + Input.GetAxis("Mouse Y") * sensitivityY;

                    rotationY = Mathf.Clamp(Mathf.Abs(rotationY), minimumY, maximumY);

                    transform.localEulerAngles = new Vector3(rotationY, transform.localEulerAngles.y, 0);

                }
            }
        }

        if (Input.GetMouseButtonDown(0))
        {
            if (IsPointerOverUIObject(Input.mousePosition))//点击到UI上
            {
                //屏蔽UI 渗透场景下层
                isHoverUI = true;
            }
            if (!isHoverUI)
            {
                lastPos = Input.mousePosition;
                fixedY = transform.position.y;
            }

        }
        else if (Input.GetMouseButton(0))
        {

            if (!isHoverUI)
            {
                Vector3 offset = (Input.mousePosition - lastPos) * moveSpeed;
                if (is3D)
                {
                    transform.Translate(new Vector3(-offset.x, 0, -offset.y));
                }
                else
                {
                    transform.Translate(new Vector3(-offset.x, -offset.y, 0));
                }

                lastPos = Input.mousePosition;
                transform.position = new Vector3(transform.position.x, fixedY, transform.position.z);
            }

        }
        else if (Input.GetMouseButtonUp(0))
        {
            isHoverUI = false;
            lastPos = Vector3.zero;
        }


    }


    private void OnDestroy()
    {

    }
    /// <summary>
    ///相机有Physics Raycaster组件 通过EventSystem  可以检测到UI,3D物体
    ///没有Physics Raycaster组件 通过EventSystem 只可以检测到UI
    /// 如果Physics Raycaster组件 可以考虑选择是否要过滤3D物体
    /// </summary>
    /// <param name="screenPosition"></param>
    /// <returns></returns>
    public bool IsPointerOverUIObject(Vector2 screenPosition)
    {
        //实例化点击事件
        PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
        //将点击位置的屏幕坐标赋值给点击事件
        eventDataCurrentPosition.position = new Vector2(screenPosition.x, screenPosition.y);

        List<RaycastResult> results = new List<RaycastResult>();       
        //向点击处发射射线
        EventSystem.current.RaycastAll(eventDataCurrentPosition, results)     
        for (int i=results.Count-1;i>=0; i-- )
        {      
             if (results[i].gameObject.layer==LayerMask.NameToLayer("Default"))
             {
                results.RemoveAt(i);
             }
        }        
        return results.Count > 0;
    }
}
Unity 是一款常用的游戏开发引擎,下面以鼠标旋转缩放移动镜头的代码进行回答。 鼠标旋转镜头代码: 在 Unity 中,可以通过 Input.GetAxis("Mouse X") 和 Input.GetAxis("Mouse Y") 获取鼠标在 X、Y 轴上的移动距离,然后将这个距离乘以一个旋转速度系数来控制镜头的旋转。具体代码如下: ```csharp public float rotateSpeed = 10f; void Update() { float mouseX = Input.GetAxis("Mouse X") * rotateSpeed; float mouseY = Input.GetAxis("Mouse Y") * rotateSpeed; transform.Rotate(Vector3.up, mouseX); transform.Rotate(Vector3.left, mouseY); } ``` 鼠标缩放镜头代码: 通过鼠标的滚轮滚动获取到滚动的值,然后根据这个值来调整镜头的缩放大小。具体代码如下: ```csharp public float zoomSpeed = 10f; void Update() { float zoomAmount = Input.GetAxis("Mouse ScrollWheel") * zoomSpeed; transform.Translate(Vector3.forward * zoomAmount); } ``` 鼠标移动镜头代码: 这里使用 Input.GetAxis("Mouse X") 和 Input.GetAxis("Mouse Y") 方法来获取鼠标在 X、Y 轴上的移动距离,然后根据这个值来移动镜头。具体代码如下: ```csharp public float moveSpeed = 10f; void Update() { float moveX = Input.GetAxis("Mouse X") * moveSpeed; float moveY = Input.GetAxis("Mouse Y") * moveSpeed; transform.Translate(moveX, 0, moveY); } ``` 以上就是在 Unity 中实现鼠标旋转缩放移动镜头的代码,你可以根据需要将这些代码添加到你的项目中,并根据自己的情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tianyongheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值