如何在统一 4.6 中停止 OnBeginDrag() 中的拖动事件

how to stop Drag event in OnBeginDrag() in unity 4.6

我有一个脚本可以处理将项目拖入和拖入给定插槽。但我想添加一个功能来停止拖动特定项目。我认为最好的地方是在 OnBeginDrag 方法中,但似乎无法找到 stop/cancel 拖动事件本身的方法,这是我的一些代码

public class SlotBehaviour : MonoBehaviour, IDropHandler, IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler,IPointerClickHandler
{
    public void OnBeginDrag(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
        {
            return;
        }
        if (this.Empty) return;
        var canvas = imageItem.canvas;
        if (canvas == null) return;
        GUIManager.mouseBusy = true;
        // We have clicked something that can be dragged.
        // What we want to do is create an icon for this.
        m_DraggingIcon = new GameObject("icon");

        m_DraggingIcon.transform.SetParent(canvas.transform, false);
        m_DraggingIcon.transform.SetAsLastSibling();

        var image = m_DraggingIcon.AddComponent<Image>();
        // The icon will be under the cursor.
        // We want it to be ignored by the event system.
        m_DraggingIcon.AddComponent<IgnoreRaycast>();

        image.sprite = imageItem.sprite;
        image.rectTransform.sizeDelta = imageItem.rectTransform.sizeDelta;


        m_DraggingPlane = transform as RectTransform;

        SetDraggedPosition(eventData);

    }

    public void OnDrag(PointerEventData data)
    {
        if (m_DraggingIcon != null)
            SetDraggedPosition(data);
    }

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

        var rt = m_DraggingIcon.GetComponent<RectTransform>();
        Vector3 globalMousePos;
        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_DraggingPlane, data.position, data.pressEventCamera, out globalMousePos))
        {
            rt.position = globalMousePos;
            rt.rotation = m_DraggingPlane.rotation;
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (m_DraggingIcon != null)
        {

            Destroy(m_DraggingIcon);
        }
        GUIManager.mouseBusy = false;
        //if you drop it somewhere where its not wanted(or just nowhere)
        if (eventData.used == false)
        {
            if (eventData.pointerCurrentRaycast.gameObject == null)// if its nowhere offer to drop it on ground
            {
                GUIManager.instance.DropItem((int)ItemsDatabase.container[containerID].items[indexInContainer]);
            }
        }
    }
}

我之前试过返回该方法,但它没有做任何事情,可能需要对事件数据做一些事情...如果你告诉我如何处理它,我将不胜感激。

您可以创建标志(例如,IsDragable)。对于您不想拖放的项目,您必须 return 来自拖动事件处理程序:

public class DragHangler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {

public bool IsDragable;

#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
    if (!IsDragable)    return;

    Debug.Log ("OnBeginDrag:Do something");
}
#endregion

#region IDragHandler implementation

public void OnDrag (PointerEventData eventData)
{
    if (!IsDragable)    return;

    Debug.Log ("OnDrag: Do something");
}

#endregion

#region IEndDragHandler implementation

public void OnEndDrag (PointerEventData eventData)
{
    if (!IsDragable) return;

    Debug.Log ("OnEnd: Do something");
}

#endregion
}

其他解决方案是在 CanvasGroup 组件中禁用 BlockRaycast

仅使用 "return" 不会取消任何内容。

相反,您可以修改传递给 OnBeginDrag 函数的 PointerEventData 信息 - 具体来说,将 pointerDrag 设置为 null。这将取消拖动:

eventData.pointerDrag = null;

设置 null 在 2020 年似乎不起作用:/

提醒,似乎在 2020 年不起作用。OnDrag 仍会被调用。

这是一个有效的标记解决方案。请注意,您必须在逻辑上使用 mouse-down?但没有其他现实的方法:/

using UnityEngine;
using UnityEngine.EventSystems;

public class CancellableDragBase : MonoBehaviour,
    IBeginDragHandler, IDragHandler, IEndDragHandler,
    IPointerUpHandler
{
    bool cancelDrag = false;

    public virtual void OnBeginDragCancellable() {}
    public virtual void OnDragCancellable() {}
    public virtual void OnEndDragCancellable() { }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (cancelDrag)
        {
            return;
        }
        OnBeginDragCancellable();
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (cancelDrag)
        {
            return;
        }
        OnDragCancellable();
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (cancelDrag)
        {
            cancelDrag = false;
            return;
        }
        OnEndDragCancellable();
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        if (cancelDrag)
        {
            cancelDrag = false;
            return;
        }
    }

    public void CancelDragIfAny()
    {
        if (Input.GetMouseButton(0))
        {
            cancelDrag = true;
        }
        else
        {
        }
    }
}

真麻烦。