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()
    {

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

        List results = new List();       
        //向点击处发射射线
        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)