美文网首页
unity 拖动UI

unity 拖动UI

作者: WOTTOW | 来源:发表于2020-01-10 13:39 被阅读0次

    主要思想: 我在canvas 模拟一个点,并从这个点发射射线,这个模拟点根据鼠标的位置进行移动,射线检测到UI并返回一个List,我从这个List中获取 想要的物体。
    既然我们已经拿到了物体,其它的就是一些基本的逻辑处理。

    测试demo:

    注意

    我添加三个标签:
    empty 判断格子是空的
    image 图片交换的标签
    bg 图片背景的标签(可以不要)
    (这种写法,把不需要UI交互的,要把UI的射线关了)


    image.png

    我给需要交互的UI添加CanvasGroup,目的是为了检测UI叠加时,检测下面一个物体。

    鼠标按下

    当我鼠标按下,会发射一次射线,获取我鼠标当前的物体的tag,判断是否可以拖动,如果可以拖动并记录位置信息,并关闭CanvasGroup的blocksRaycasts。记录位置信息目的是当天图片与另一张图片替换时,另一张图片需要移动的位置。blocksRaycasts=false的目的是,穿透鼠标当前有图片,检测下面的图片

    鼠标拖动

    直接把鼠标的位置赋值给UI就ok了。

    鼠标抬起

    当我鼠标抬起,会发射一次射线,获取我鼠标当前的物体的tag,判断是否可以放下,替换,返回开始位置,并把拖动图片的blocksRaycasts开启(防止穿透)

    效果图

    image.gif
        public EventSystem eventSystem;
        public StandaloneInputModule standaloneInputModule;
        public GameObject canvas;
    
        private PointerEventData pointerEventData;
        private GraphicRaycaster gr;
        private CanvasGroup itemCanvasGroup;
    
        private Transform currntGameObject;      //当前拖动的物体
        private Transform swpObj;                //交换的物体
    
        private string targetTag = "empty";      //判断格子是空的
        private string swapTag = "image";        //图片交换的标签
        private string bgTag = "bg";             //图片背景的标签
    
        private Vector3 startPos;                //鼠标之前的位置
        private Vector3 endPos;                  //结束的位置
    
        private bool Stop = false;
    
        private List<RaycastResult> mousMoveResults = new List<RaycastResult>();
    
        private void Start()
        {
            gr = canvas.GetComponent<GraphicRaycaster>();
        }
    
        private void Update()
        {
            GetOverUI();
        }
    
        /// <summary>
        /// 获取鼠标停留处UI
        /// </summary>
        /// <returns></returns>
        public void GetOverUI()
        {
            if (Input.GetMouseButtonDown(0))
            {
                GetTransform(out currntGameObject, out startPos);
                if (currntGameObject != null&& currntGameObject.tag.Contains(swapTag))
                {
                    currntGameObject.transform.SetAsLastSibling();
                    Stop = false;
                }
                else
                {
                    Stop = true;
                }
            }
            if (!Stop)
            {
                if (Input.GetMouseButton(0))
                {
                    ContinuedMouseButtonDowm();
                }
    
                if (Input.GetMouseButtonUp(0))
                {
                    SwpObjPos();
                    if (itemCanvasGroup != null)
                        itemCanvasGroup.blocksRaycasts = true;
                }
            }
        }
    
        /// <summary>
        /// 持续鼠标按下
        /// </summary>
        private void ContinuedMouseButtonDowm()
        {
            if (itemCanvasGroup == null || itemCanvasGroup.blocksRaycasts)
            {
                itemCanvasGroup = currntGameObject.GetComponent<CanvasGroup>();
                itemCanvasGroup.blocksRaycasts = false;
            }
            currntGameObject.transform.position = Input.mousePosition;
        }
    
        /// <summary>
        /// 交换物体的位置
        /// </summary>
        private void SwpObjPos()
        {
            GetTransform(out swpObj, out endPos);
    
            if (swpObj == null)
            {
                currntGameObject.position = startPos;
            }
            else if (swpObj.tag.Contains(targetTag))
            {
                currntGameObject.position = swpObj.position;
            }
            else if (swpObj.tag.Contains(swapTag))
            {
                swpObj.position = startPos;
                currntGameObject.position = endPos;
            }
            else
            {
                currntGameObject.position = startPos;
            }
        }
    
        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="getTra">返回获取的物体</param>
        /// <param name="record">记录鼠标当前的坐标</param>
        private void GetTransform(out Transform getTra, out Vector3 record)
        {
            mousMoveResults.Clear();
            if (pointerEventData == null)
                pointerEventData = new PointerEventData(EventSystem.current);
            pointerEventData.position = Input.mousePosition;
            gr.Raycast(pointerEventData, mousMoveResults);
            if (mousMoveResults.Count != 0)
            {
                getTra = mousMoveResults[0].gameObject.transform;
                record = getTra.position;
            }
            else
            {
                getTra = null;
                record = Vector3.zero;
            }
        }
    
        /// <summary>
        /// 清空mousMoveResults
        /// </summary>
        private void ClearMousMoveResultsList()
        {
            mousMoveResults.Clear();
        }
    

    相关文章

      网友评论

          本文标题:unity 拖动UI

          本文链接:https://www.haomeiwen.com/subject/bwjsactx.html