当前位置: 首页 > news >正文

UI图像拖动更换

今天做一个拖动图像的demo,效果图如下:

 

1 拖动的类需要实现 IDropHandler, IPointerEnterHandler, IPointerExitHandler 这三个接口;

2 接受的类需要实现 IBeginDragHandler,IDragHandler,IEndDragHandler 这三个接口:

下面贴代码

Drag.cs

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

//拖动要集成三个接口:IBeginDragHandler,IDragHandler,IEndDragHandler
[RequireComponent(typeof(Image))]
public class Drag : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler {
    //是否与面板保持平行
    public bool dragOnSurfaces = true;

    private GameObject m_DragIcon;
    private RectTransform m_RectPlane;


    public void OnBeginDrag(PointerEventData eventData)
    {
        var canvas = FindInParent<Canvas>(gameObject);
        if (canvas == null) return;

        //创建临时拖动对象名为“Icon”
        m_DragIcon = new GameObject("Icon");
        //为拖动对象设置画布
        m_DragIcon.transform.SetParent(canvas.transform, false);
        //设置为同级最后
        m_DragIcon.transform.SetAsLastSibling();

        var image = m_DragIcon.AddComponent<Image>();
        //拖动对象忽略事件响应
        m_DragIcon.AddComponent<IgnoreRaycast>();

        image.sprite = gameObject.GetComponent<Image>().sprite;
        image.SetNativeSize();

        if (dragOnSurfaces)
            m_RectPlane = transform as RectTransform;
        else
            m_RectPlane = canvas.transform as RectTransform;
        
        //拖动对象跟随光标
        SetDraggedPosition(eventData);
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (m_DragIcon != null)
            SetDraggedPosition(eventData);
    }

    private void SetDraggedPosition(PointerEventData data)
    {
        if (dragOnSurfaces && data.pointerEnter != null && data.pointerEnter.transform as RectTransform != null)
            m_RectPlane = data.pointerEnter.transform as RectTransform;

        var rt = m_DragIcon.GetComponent<RectTransform>();
        // 屏幕点在矩形内的世界坐标
        Vector3 globalMousePos;
        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_RectPlane,data.position,data.pressEventCamera,out globalMousePos))
        {
            rt.position = globalMousePos;
            rt.rotation = m_RectPlane.rotation;
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        //释放删除临时对象
        if (m_DragIcon != null)
            Destroy(m_DragIcon);
    }

    static public T FindInParent<T>(GameObject go) where T:Component
    {
        if (go == null) return null;

        var comp = go.GetComponent<T>();
        if (comp != null)
            return comp;

        Transform temp = go.transform.parent;
        while (temp != null && comp == null)
        {
            comp = temp.gameObject.GetComponent<T>();
            if (comp != null)
                return comp;

            temp = temp.parent;
        }

        return comp;
    }
}

 

Drop.cs

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

//接收拖动的类需要实现的三个接口:IDropHandler, IPointerEnterHandler, IPointerExitHandler
public class Drop : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler
{
    public Image containerImage;
    public Image receivingImage;
    private Color normalColor;
    public Color highLightColor = Color.blue;

    public void OnEnable()
    {
        if (containerImage != null)
            normalColor = containerImage.color;
    }
    //释放对象
    public void OnDrop(PointerEventData eventData)
    {
        containerImage.color = normalColor;
        //没有图像直接返回
        if (receivingImage == null)
            return;
        Sprite dropSprite = GetDropSprite(eventData);
        if (dropSprite != null)
            receivingImage.sprite = dropSprite;
    }
    //对象移到接受面板,面板高亮
    public void OnPointerEnter(PointerEventData eventData)
    {
        if (containerImage == null)
            return;

        Sprite dropSprite = GetDropSprite(eventData);
        if (dropSprite != null)
            containerImage.color = highLightColor;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        if (containerImage == null)
            return;
        containerImage.color = normalColor;
    }

    //获取图像数据
    private Sprite GetDropSprite(PointerEventData data)
    {
        var originalObj = data.pointerDrag;
        if (originalObj == null)
            return null;

        var srcImage = originalObj.GetComponent<Image>();
        if (srcImage == null)
            return null;

        return srcImage.sprite;
    }
}

 

demo源文件 http://files.cnblogs.com/files/lu-xi/DragAndDrop.zip

 

转载于:https://www.cnblogs.com/lu-xi/p/6706751.html

相关文章:

  • Mysql避免全表扫描sql查询优化 .
  • LR杂记 - 性能測试指标及经常使用的监控工具
  • linux常见问题汇总
  • jps命令
  • 招投标流程
  • 从零开始教你制作友善之壁TINY4412----SD卡uboot启动卡
  • Linux centos 连接网络
  • Action代理类的工作
  • 字符串中的转义字符与字符串的长度
  • 测试图片
  • php排序
  • 使用tomcat数据源(JNDI)
  • windows单节点下安装es集群
  • CentOS 7 安装配置LAMP服务器方法(Apache+PHP+MariaDB)
  • 移动开发技术新趋向(一)
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • C# 免费离线人脸识别 2.0 Demo
  • Java的Interrupt与线程中断
  • Lucene解析 - 基本概念
  • Making An Indicator With Pure CSS
  • Next.js之基础概念(二)
  • SpringCloud集成分布式事务LCN (一)
  • 区块链技术特点之去中心化特性
  • 使用agvtool更改app version/build
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 消息队列系列二(IOT中消息队列的应用)
  • 怎样选择前端框架
  • Java数据解析之JSON
  • 如何正确理解,内页权重高于首页?
  • ​批处理文件中的errorlevel用法
  • #《AI中文版》V3 第 1 章 概述
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (pojstep1.1.2)2654(直叙式模拟)
  • (多级缓存)缓存同步
  • *p++,*(p++),*++p,(*p)++区别?
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET NPOI导出Excel详解
  • .net 中viewstate的原理和使用
  • @Bean, @Component, @Configuration简析
  • [ C++ ] STL---仿函数与priority_queue
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [Android实例] 保持屏幕长亮的两种方法 [转]
  • [BZOJ]4817: [Sdoi2017]树点涂色
  • [BZOJ1008][HNOI2008]越狱
  • [C++]指针与结构体
  • [CareerCup] 2.1 Remove Duplicates from Unsorted List 移除无序链表中的重复项
  • [CERC2017]Cumulative Code
  • [hdu 3746] Cyclic Nacklace [kmp]
  • [IE技巧] IE8中HTTP连接数目的变化
  • [iOS]让Xcode 4.2生成的app支持老的iOS设备(armv6)
  • [Java][方法引用]构造方法的引用事例分析
  • [Labtools 27-1429] XML parser encountered a problem in file
  • [LeetBook]【学习日记】数组内乘积
  • [leetcode] Multiply Strings
  • [Linux] day07——查看及过滤文本