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源文件 https://files.cnblogs.com/files/lu-xi/DragAndDrop.zip

原文地址:https://www.cnblogs.com/lu-xi/p/6706751.html