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. 68
      Assets/Fungus/Sprite/Scripts/Clickable2D.cs
  2. 169
      Assets/Fungus/Sprite/Scripts/Draggable2D.cs
  3. 787
      Assets/FungusExamples/DragAndDrop/DragAndDrop.unity

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

@ -4,9 +4,7 @@
*/
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System.Collections;
namespace Fungus
{
@ -15,7 +13,7 @@ namespace Fungus
* The Game Object must have a Collider2D component attached.
* Use in conjunction with the ObjectClicked Flowchart event handler.
*/
public class Clickable2D : MonoBehaviour
public class Clickable2D : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler
{
[Tooltip("Is object clicking enabled")]
public bool clickEnabled = true;
@ -23,35 +21,19 @@ namespace Fungus
[Tooltip("Mouse texture to use when hovering mouse over object")]
public Texture2D hoverCursor;
protected virtual void OnMouseDown()
{
if (!clickEnabled)
{
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()
{
if (EventSystem.current.IsPointerOverGameObject())
{
return; // Ignore this mouse event, pointer is over UI
}
protected virtual void Start()
{
// 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;
changeCursor(hoverCursor);
}
var raycast = Camera.main.GetComponent<Physics2DRaycaster>();
if (raycast == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}
protected virtual void OnMouseExit()
{
@ -68,6 +50,30 @@ namespace Fungus
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
}
}

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

@ -4,9 +4,10 @@
*/
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
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.
* 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")]
public bool dragEnabled = true;
@ -39,38 +40,20 @@ namespace Fungus
protected bool updatePosition = false;
protected Vector3 newPosition;
protected Vector3 delta = Vector3.zero;
protected virtual void OnMouseDown()
{
// 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);
}
}
protected virtual void OnMouseDrag()
{
if (!dragEnabled)
{
return;
}
float x = Input.mousePosition.x;
float y = Input.mousePosition.y;
float z = transform.position.z;
protected virtual void Start()
{
// 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;
newPosition = Camera.main.ScreenToWorldPoint(new Vector3(x, y, 10f)) - delta;
newPosition.z = z;
updatePosition = true;
}
var raycast = Camera.main.GetComponent<Physics2DRaycaster>();
if (raycast == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}
protected virtual void LateUpdate()
{
@ -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)
{
if (!dragEnabled)
@ -186,6 +127,86 @@ namespace Fungus
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