美文网首页
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

    主要思想: 我在canvas 模拟一个点,并从这个点发射射线,这个模拟点根据鼠标的位置进行移动,射线检测到UI并返...

  • Unity之NGUI插件(一)

    前言:关于Unity中关于UI的插件,我们最开始学的是UGUI,是Unity自带的UI系统,而在Unity版本还没...

  • unity 鼠标拖动

    using UnityEngine; using System.Collections; public class...

  • 【Unity】优化UI(二)

    Unity UI的基本原理 理解Unity UI系统的组成部分是很重要的。有几个基础的类和组件共同组成了UI系统。...

  • Unity学习笔记 - uGUI

    uGUI就是Unity原生自带的UI制作系统,unity 4.6之后才有的。据说比NGUI好用,毕竟是unity亲...

  • Unity 拖动惯性效果

    缓冲时间可以自己调using UnityEngine;using System.Collections; publ...

  • 拖动手势UIPanGestureRecognizer

    1.拖动手势简介拖动手势(UIPanGestureRecognizer)可以修改一个UI控件的位置,在有些游戏类A...

  • Unity技术之UGUI-SpriteAtlas(图集)查看工具

    Unity技术之UGUI-SpriteAtlas(图集)查看工具 简介 Unity提供了UGUI用于UI系统的制作...

  • 【Unity】优化UI(一)

    Unity UI 优化引导 优化Unity UI是一门艺术。又快又见效的方法很罕见,每一种情况都必须仔细思考系统的...

  • Unity 序列化泛型多维数组

    为了能够在Unity的监视面板拖动或者调整数据,Unity本身不支持多维数组的序列化,所以要做个包装。 2B青年:...

网友评论

      本文标题:unity 拖动UI

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