Browse Source

Fixed Clickable2D and Draggable2D to use event system to correctly block clicks on UI elements.

Updated drag and drop demo scene.
master
Christopher 8 years ago
parent
commit
6c0dfba807
  1. 58
      Assets/Fungus/Sprite/Scripts/Clickable2D.cs
  2. 161
      Assets/Fungus/Sprite/Scripts/Draggable2D.cs
  3. 787
      Assets/FungusExamples/DragAndDrop/DragAndDrop.unity

58
Assets/Fungus/Sprite/Scripts/Clickable2D.cs

@ -4,9 +4,7 @@
*/ */
using UnityEngine; using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
using System.Collections;
namespace Fungus namespace Fungus
{ {
@ -15,7 +13,7 @@ namespace Fungus
* The Game Object must have a Collider2D component attached. * The Game Object must have a Collider2D component attached.
* Use in conjunction with the ObjectClicked Flowchart event handler. * Use in conjunction with the ObjectClicked Flowchart event handler.
*/ */
public class Clickable2D : MonoBehaviour public class Clickable2D : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler
{ {
[Tooltip("Is object clicking enabled")] [Tooltip("Is object clicking enabled")]
public bool clickEnabled = true; public bool clickEnabled = true;
@ -23,34 +21,18 @@ namespace Fungus
[Tooltip("Mouse texture to use when hovering mouse over object")] [Tooltip("Mouse texture to use when hovering mouse over object")]
public Texture2D hoverCursor; public Texture2D hoverCursor;
protected virtual void OnMouseDown() protected virtual void Start()
{
if (!clickEnabled)
{ {
// If the main camera doesn't already have a Physics2DRaycaster then add one automatically to
// use UI raycasts for hit detection. This allows UI to block clicks on objects behind.
if (Camera.main == null)
return; return;
}
if (EventSystem.current.IsPointerOverGameObject())
{
return; // Ignore this mouse event, pointer is over UI
}
// TODO: Cache these object for faster lookup
ObjectClicked[] handlers = GameObject.FindObjectsOfType<ObjectClicked>();
foreach (ObjectClicked handler in handlers)
{
handler.OnObjectClicked(this);
}
}
protected virtual void OnMouseEnter() var raycast = Camera.main.GetComponent<Physics2DRaycaster>();
if (raycast == null)
{ {
if (EventSystem.current.IsPointerOverGameObject()) Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
{
return; // Ignore this mouse event, pointer is over UI
} }
changeCursor(hoverCursor);
} }
protected virtual void OnMouseExit() protected virtual void OnMouseExit()
@ -68,6 +50,30 @@ namespace Fungus
Cursor.SetCursor(cursorTexture, Vector2.zero, CursorMode.Auto); Cursor.SetCursor(cursorTexture, Vector2.zero, CursorMode.Auto);
} }
#region IPointerClickHandler implementation
public void OnPointerClick(PointerEventData eventData)
{
if (!clickEnabled)
{
return;
}
// TODO: Cache these object for faster lookup
ObjectClicked[] handlers = GameObject.FindObjectsOfType<ObjectClicked>();
foreach (ObjectClicked handler in handlers)
{
handler.OnObjectClicked(this);
}
}
#endregion
#region IPointerEnterHandler
public void OnPointerEnter(PointerEventData eventData)
{
changeCursor(hoverCursor);
}
#endregion
} }
} }

161
Assets/Fungus/Sprite/Scripts/Draggable2D.cs

@ -4,9 +4,10 @@
*/ */
using UnityEngine; using UnityEngine;
using System.Collections; using UnityEngine.EventSystems;
using UnityEngine.Serialization; using UnityEngine.Serialization;
namespace Fungus namespace Fungus
{ {
@ -17,7 +18,7 @@ namespace Fungus
* The RigidBody would typically have the Is Kinematic property set to true, unless you want the object to move around using physics. * The RigidBody would typically have the Is Kinematic property set to true, unless you want the object to move around using physics.
* Use in conjunction with the Drag Started, Drag Completed, Drag Cancelled, Drag Entered & Drag Exited event handlers. * Use in conjunction with the Drag Started, Drag Completed, Drag Cancelled, Drag Entered & Drag Exited event handlers.
*/ */
public class Draggable2D : MonoBehaviour public class Draggable2D : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{ {
[Tooltip("Is object dragging enabled")] [Tooltip("Is object dragging enabled")]
public bool dragEnabled = true; public bool dragEnabled = true;
@ -40,38 +41,20 @@ namespace Fungus
protected Vector3 newPosition; protected Vector3 newPosition;
protected Vector3 delta = Vector3.zero; protected Vector3 delta = Vector3.zero;
protected virtual void OnMouseDown() protected virtual void Start()
{ {
// Offset the object so that the drag is anchored to the exact point where the user clicked it // If the main camera doesn't already have a Physics2DRaycaster then add one automatically to
float x = Input.mousePosition.x; // use UI raycasts for hit detection. This allows UI to block clicks on objects behind.
float y = Input.mousePosition.y; if (Camera.main == null)
delta = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 10f)) - transform.position; return;
delta.z = 0f;
startingPosition = transform.position;
foreach (DragStarted handler in GetHandlers<DragStarted>()) var raycast = Camera.main.GetComponent<Physics2DRaycaster>();
if (raycast == null)
{ {
handler.OnDragStarted(this); Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
} }
} }
protected virtual void OnMouseDrag()
{
if (!dragEnabled)
{
return;
}
float x = Input.mousePosition.x;
float y = Input.mousePosition.y;
float z = transform.position.z;
newPosition = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 10f)) - delta;
newPosition.z = z;
updatePosition = true;
}
protected virtual void LateUpdate() protected virtual void LateUpdate()
{ {
// iTween will sometimes override the object position even if it should only be affecting the scale, rotation, etc. // iTween will sometimes override the object position even if it should only be affecting the scale, rotation, etc.
@ -83,48 +66,6 @@ namespace Fungus
} }
} }
protected virtual void OnMouseUp()
{
if (!dragEnabled)
{
return;
}
bool dragCompleted = false;
DragCompleted[] handlers = GetHandlers<DragCompleted>();
foreach (DragCompleted handler in handlers)
{
if (handler.draggableObject == this)
{
if (handler.IsOverTarget())
{
handler.OnDragCompleted(this);
dragCompleted = true;
if (returnOnCompleted)
{
LeanTween.move(gameObject, startingPosition, returnDuration).setEase(LeanTweenType.easeOutExpo);
}
}
}
}
if (!dragCompleted)
{
foreach (DragCancelled handler in GetHandlers<DragCancelled>())
{
handler.OnDragCancelled(this);
}
if (returnOnCancelled)
{
LeanTween.move(gameObject, startingPosition, returnDuration).setEase(LeanTweenType.easeOutExpo);
}
}
}
protected virtual void OnTriggerEnter2D(Collider2D other) protected virtual void OnTriggerEnter2D(Collider2D other)
{ {
if (!dragEnabled) if (!dragEnabled)
@ -186,6 +127,86 @@ namespace Fungus
Cursor.SetCursor(cursorTexture, Vector2.zero, CursorMode.Auto); Cursor.SetCursor(cursorTexture, Vector2.zero, CursorMode.Auto);
} }
#region IBeginDragHandler implementation
public void OnBeginDrag(PointerEventData eventData)
{
// Offset the object so that the drag is anchored to the exact point where the user clicked it
float x = Input.mousePosition.x;
float y = Input.mousePosition.y;
delta = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 10f)) - transform.position;
delta.z = 0f;
startingPosition = transform.position;
foreach (DragStarted handler in GetHandlers<DragStarted>())
{
handler.OnDragStarted(this);
}
}
#endregion
#region IDragHandler implementation
public void OnDrag(PointerEventData eventData)
{
if (!dragEnabled)
{
return;
}
float x = Input.mousePosition.x;
float y = Input.mousePosition.y;
float z = transform.position.z;
newPosition = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 10f)) - delta;
newPosition.z = z;
updatePosition = true;
}
#endregion
#region IEndHandler implementation
public void OnEndDrag(PointerEventData eventData)
{
if (!dragEnabled)
{
return;
}
bool dragCompleted = false;
DragCompleted[] handlers = GetHandlers<DragCompleted>();
foreach (DragCompleted handler in handlers)
{
if (handler.draggableObject == this)
{
if (handler.IsOverTarget())
{
handler.OnDragCompleted(this);
dragCompleted = true;
if (returnOnCompleted)
{
LeanTween.move(gameObject, startingPosition, returnDuration).setEase(LeanTweenType.easeOutExpo);
}
}
}
}
if (!dragCompleted)
{
foreach (DragCancelled handler in GetHandlers<DragCancelled>())
{
handler.OnDragCancelled(this);
}
if (returnOnCancelled)
{
LeanTween.move(gameObject, startingPosition, returnDuration).setEase(LeanTweenType.easeOutExpo);
}
}
}
#endregion
} }
} }

787
Assets/FungusExamples/DragAndDrop/DragAndDrop.unity

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save