如何在统一 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
{
}
}
}
真麻烦。
我有一个脚本可以处理将项目拖入和拖入给定插槽。但我想添加一个功能来停止拖动特定项目。我认为最好的地方是在 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
{
}
}
}
真麻烦。