unity 鼠标移动 缩放,旋转

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

tianyongheng

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

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

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

打赏作者

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

抵扣说明:

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

余额充值