Reputation: 138
I have a script that handles dragging of an items from and to a given slot. But i want to add a function to stop dragging of a specific items. i think the best place to do is in the OnBeginDrag
method, but cant seem to figure a way to stop/cancel the drag event itself, here is a bit of my code
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]);
}
}
}
}
I tried returning the method earlier but it doesnt do anything, probably need to do something with the event data...i will be gratefull if you tell me how to deal with it.
Upvotes: 11
Views: 22412
Reputation: 12353
Alert, seems to not work in 2020. OnDrag still gets called.
Here's a flag solution that works. Note you have to logically use mouse-down? but there's no other realistic way :/
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
{
}
}
}
What a hassle.
Upvotes: -1
Reputation: 511
Just using "return" doesn't cancel anything.
Instead, you can modify the PointerEventData info that is passed into the OnBeginDrag function - specifically, set pointerDrag to null. This will cancel the drag:
eventData.pointerDrag = null;
Upvotes: 51
Reputation: 2130
You may create flag (for example, IsDragable). For items which you donn't want to drag&drop you have to return from drag event handlers:
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
}
Other solution is to disable BlockRaycast in CanvasGroup component.
Upvotes: -6