unity 实现拖动ui填空,并判断对错

参考:https://ask.csdn.net/questions/7971448

根据自己的需求修改为如下代码

使用过程中,出现拖动ui位置错误的情况,修改为使用 localPosition
但是吸附到指定位置却需要用的position

    public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    {
        private RectTransform dragTransform;
        private Vector2 initPosition;
        private Vector2 startPosition;

        [Header("正确区域")]
        public RectTransform targetArea;

        [Header("初始区域")]
        public RectTransform originalArea;
        [Header("错误区域")]
        public RectTransform[] targetOtherArea;

        private bool result;    //拖动结果
        private bool valid;     //拖动有效

        public bool Result { get => result; private set => result = value; }
        public bool Valid { get => valid; private set => valid = value; }

        public void Awake()
        {
            dragTransform = GetComponent<RectTransform>();

            //初始位置
            initPosition = dragTransform.localPosition;
        }

        /// <summary>
        /// 重置位置
        /// </summary>
        public void ResetPos()
        {
            dragTransform.localPosition = initPosition;
            result = false;
            valid = false;
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            //开始拖动的位置
            startPosition = dragTransform.localPosition;

            //设置UI最后渲染
            dragTransform.SetAsLastSibling();
        }

        public void OnDrag(PointerEventData eventData)
        {
            dragTransform.localPosition = GetLocalPosition(eventData.position);
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            result = RectTransformUtility.RectangleContainsScreenPoint(targetArea, eventData.position);
#if UNITY_EDITOR
            Debug.Log($"拖动结果: {result}");
#endif
            if (result)
            {
                //吸附到目标位置
                dragTransform.position = targetArea.position;
                valid = true;
                return;
            }
            else
            {
                foreach (var item in targetOtherArea)
                {
                    if (RectTransformUtility.RectangleContainsScreenPoint(item, eventData.position))
                    {
                        //吸附到目标位置
                        dragTransform.position = item.position;
                        valid = true;
                        return;
                    }
                }
                //原始位置,拖动无效
                if (RectTransformUtility.RectangleContainsScreenPoint(originalArea, eventData.position))
                {
                    //吸附到目标位置
                    dragTransform.position = originalArea.position;
                    valid = false;
                    return;
                }
            }

            //其它情况还原为开始拖动的位置
            valid = false;
            dragTransform.localPosition = startPosition;
        }

        private Vector2 GetLocalPosition(Vector2 screenPosition)
        {
            Vector2 localPosition = Vector2.zero;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(dragTransform.parent as RectTransform, screenPosition, null, out localPosition);
            return localPosition;
        }
    }

Demo

using MyTool.Tools;
using UnityEngine;
using UnityEngine.UI;

public class Demo : MonoBehaviour
{
    public DragAndDrop dragAndDrop;
    public Button okBtn;

    // Start is called before the first frame update
    void Start()
    {
        okBtn.onClick.AddListener(OnClickOkBtn);
    }

    private void Update()
    {
        okBtn.interactable = dragAndDrop.Valid;
    }

    void OnClickOkBtn()
    {
        if (dragAndDrop.Result)
        {
            Debug.Log("恭喜你答对了!");
        }
        else
        {
            Debug.Log("很遗憾,没有答对!");
        }
    }
}

ui搭建
在这里插入图片描述
效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值