如何在Unity 4.6中的OnBeginDrag()中停止Drag事件

时间:2015-01-28 21:10:12

标签: c# events unity3d drag-and-drop

我有一个脚本可以处理从一个插槽到另一个插槽的项目拖动。但我想添加一个函数来停止拖动特定的项目。我认为最好的地方是OnBeginDrag方法,但似乎无法想办法停止/取消拖动事件本身,这里有一些我的代码

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]);
            }
        }
    }
}

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

3 个答案:

答案 0 :(得分:25)

只使用“return”不会取消任何内容。

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

eventData.pointerDrag = null;

答案 1 :(得分:2)

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

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

答案 2 :(得分:-1)

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

警报,似乎在2020年不起作用。OnDrag仍然会被调用。

这是一个有效的标志解决方案。注意您必须在逻辑上使用鼠标向下键吗?但是没有其他现实的方法:/

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
        {
        }
    }
}

真麻烦。