Created
November 10, 2020 15:20
-
-
Save wakeup5/c929daa1ffd517c3d9dbeb642daf329b to your computer and use it in GitHub Desktop.
Unity UGUI Drag and Drop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using UniRx; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
namespace Waker.UI.DragAndDrop | |
{ | |
public class DragAndDropManager : MonoBehaviour | |
{ | |
[SerializeField] private GameObject dragObject; | |
[SerializeField] private Vector2 dragOffset; | |
[SerializeField] private Canvas canvas; | |
private DragAndDropSlot pressedDragSlot; | |
private RectTransform rectTransform; | |
private RectTransform dragObjectTransform; | |
private Camera canvasCamera; | |
private Subject<DragEvent> onBeginDrag = new Subject<DragEvent>(); | |
private Subject<DropEvent> onDrop = new Subject<DropEvent>(); | |
private Subject<DragEvent> onEndDragWithoutDrop = new Subject<DragEvent>(); | |
public IObservable<DragEvent> BeginDragAsObservable() => onBeginDrag; | |
public IObservable<DropEvent> DropAsObservable() => onDrop; | |
public IObservable<DragEvent> EndDragWithoutDropAsObservable() => onEndDragWithoutDrop; | |
private void Awake() | |
{ | |
// Set variables | |
rectTransform = transform as RectTransform; | |
dragObject.SetActive(false); | |
dragObject.transform.SetParent(transform); | |
dragObjectTransform = dragObject.transform as RectTransform; | |
canvasCamera = canvas.worldCamera; | |
if (canvasCamera == null) | |
{ | |
canvasCamera = Camera.main; | |
} | |
} | |
internal void OnBeginDrag(DragAndDropSlot slot, PointerEventData eventData) | |
{ | |
pressedDragSlot = slot; | |
dragObject.SetActive(true); | |
if (RectTransformUtility.ScreenPointToLocalPointInRectangle( | |
rectTransform, | |
eventData.position, | |
canvasCamera, | |
out var localPoint)) | |
{ | |
dragObjectTransform.anchoredPosition = localPoint + dragOffset; | |
} | |
DragEvent dragEvent = new DragEvent(this, pressedDragSlot, dragObject); | |
onBeginDrag.OnNext(dragEvent); | |
ExecuteEvents.Execute<IDragAndDropHandler>(pressedDragSlot.gameObject, null, (o, a) => o.OnBeginDrag(dragEvent)); | |
} | |
internal void OnDrag(DragAndDropSlot slot, PointerEventData eventData) | |
{ | |
if (pressedDragSlot == null) | |
{ | |
return; | |
} | |
if (RectTransformUtility.ScreenPointToLocalPointInRectangle( | |
rectTransform, | |
eventData.position, | |
canvasCamera, | |
out var localPoint)) | |
{ | |
dragObjectTransform.anchoredPosition = localPoint + dragOffset; | |
} | |
} | |
internal void OnEndDrag(DragAndDropSlot slot, PointerEventData eventData) | |
{ | |
if (pressedDragSlot == null) | |
{ | |
return; | |
} | |
DragEvent dragEvent = new DragEvent(this, pressedDragSlot, dragObject); | |
onEndDragWithoutDrop.OnNext(dragEvent); | |
ExecuteEvents.Execute<IDragAndDropHandler>(pressedDragSlot.gameObject, null, (o, a) => o.OnEndDragWithoutDrop(dragEvent)); | |
pressedDragSlot = null; | |
dragObject.SetActive(false); | |
} | |
internal void OnDrop(DragAndDropSlot slot, PointerEventData eventData) | |
{ | |
if (pressedDragSlot == null) | |
{ | |
return; | |
} | |
DropEvent dropEvent = new DropEvent(this, pressedDragSlot, slot, dragObject); | |
onDrop.OnNext(dropEvent); | |
ExecuteEvents.Execute<IDragAndDropHandler>(pressedDragSlot.gameObject, null, (o, a) => o.OnDrop(dropEvent)); | |
ExecuteEvents.Execute<IDragAndDropHandler>(slot.gameObject, null, (o, a) => o.OnDrop(dropEvent)); | |
pressedDragSlot = null; | |
dragObject.SetActive(false); | |
} | |
public void StopDrag() | |
{ | |
DragEvent dragEvent = new DragEvent(this, pressedDragSlot, dragObject); | |
onEndDragWithoutDrop.OnNext(dragEvent); | |
ExecuteEvents.Execute<IDragAndDropHandler>(pressedDragSlot.gameObject, null, (o, a) => o.OnEndDragWithoutDrop(dragEvent)); | |
pressedDragSlot = null; | |
dragObject.SetActive(false); | |
} | |
} | |
public struct DropEvent | |
{ | |
public DragAndDropSlot dragSlot; | |
public DragAndDropSlot dropSlot; | |
public GameObject dragObject; | |
public DropEvent(DragAndDropManager manager, DragAndDropSlot dragSlot, DragAndDropSlot dropSlot, GameObject dragObject) | |
{ | |
this.dragSlot = dragSlot; | |
this.dropSlot = dropSlot; | |
this.dragObject = dragObject; | |
} | |
} | |
public struct DragEvent | |
{ | |
private DragAndDropManager manager; | |
public DragAndDropSlot dragSlot; | |
public GameObject dragObject; | |
public DragEvent(DragAndDropManager manager, DragAndDropSlot dragSlot, GameObject dragObject) | |
{ | |
this.manager = manager; | |
this.dragSlot = dragSlot; | |
this.dragObject = dragObject; | |
} | |
public void StopDrag() | |
{ | |
manager.StopDrag(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UniRx; | |
using UnityEngine; | |
using UnityEngine.EventSystems; | |
using UnityEngine.UI; | |
namespace Waker.UI.DragAndDrop | |
{ | |
public class DragAndDropSlot : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IInitializePotentialDragHandler//, IPointerDownHandler, IPointerClickHandler | |
{ | |
[SerializeField] private bool activeScrolling = false; | |
private ScrollRect scrollRect; | |
private Button button; | |
private bool isScroll = false; | |
private DragAndDropManager manager; | |
private void OnEnable() | |
{ | |
scrollRect = GetComponentInParent<ScrollRect>(); | |
button = GetComponent<Button>(); | |
manager = GetComponentInParent<DragAndDropManager>(); | |
} | |
public void OnBeginDrag(PointerEventData eventData) | |
{ | |
if (button) button.interactable = false; | |
if (activeScrolling && WhetherScrolling(scrollRect, eventData.delta)) | |
{ | |
scrollRect.OnBeginDrag(eventData); | |
isScroll = true; | |
return; | |
} | |
if (manager) manager.OnBeginDrag(this, eventData); | |
} | |
public void OnDrag(PointerEventData eventData) | |
{ | |
if (activeScrolling && scrollRect && isScroll) | |
{ | |
scrollRect.OnDrag(eventData); | |
return; | |
} | |
if (manager) manager.OnDrag(this, eventData); | |
} | |
public void OnEndDrag(PointerEventData eventData) | |
{ | |
if (button) button.interactable = true; | |
if (activeScrolling && scrollRect && isScroll) | |
{ | |
scrollRect.OnEndDrag(eventData); | |
isScroll = false; | |
return; | |
} | |
if (manager) | |
{ | |
if (eventData.pointerCurrentRaycast.gameObject?.GetComponentInParent<DragAndDropSlot>() == this) | |
{ | |
OnDrop(eventData); | |
return; | |
} | |
manager.OnEndDrag(this, eventData); | |
} | |
} | |
public void OnDrop(PointerEventData eventData) | |
{ | |
if (manager) manager.OnDrop(this, eventData); | |
} | |
public void OnInitializePotentialDrag(PointerEventData eventData) | |
{ | |
if (scrollRect) scrollRect.OnInitializePotentialDrag(eventData); | |
} | |
public void StopDrag() | |
{ | |
if (manager) manager.StopDrag(); | |
} | |
private static bool WhetherScrolling(ScrollRect scroll, Vector2 delta) | |
{ | |
if (!scroll) | |
{ | |
return false; | |
} | |
if (scroll.horizontal && scroll.vertical) | |
{ | |
return true; | |
} | |
if (scroll.horizontal && Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) | |
{ | |
return true; | |
} | |
if (scroll.vertical && Mathf.Abs(delta.x) < Mathf.Abs(delta.y)) | |
{ | |
return true; | |
} | |
return false; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine.EventSystems; | |
namespace Waker.UI.DragAndDrop | |
{ | |
public interface IDragAndDropHandler : IEventSystemHandler | |
{ | |
void OnBeginDrag(DragEvent e); | |
void OnEndDragWithoutDrop(DragEvent e); | |
void OnDrop(DropEvent e); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region 드래그 앤 드랍 이벤트 | |
public void OnBeginDrag(DragEvent e) | |
{ | |
if (!item.Opened || !(item is IArmsItem arms)) | |
{ | |
e.StopDrag(); | |
return; | |
} | |
var itemInfo = e.dragObject.GetComponent<ItemInfo>(); | |
itemInfo.SetItemData(arms.ItemData); | |
itemInfo.SetItemLevel(arms.Level); | |
itemInfo.SetItemStar(arms.Star); | |
} | |
public void OnEndDragWithoutDrop(DragEvent e) | |
{ | |
// Do nothing... | |
} | |
public void OnDrop(DropEvent e) | |
{ | |
var equipSlot = e.dropSlot.GetComponent<UIEquipSlot>(); | |
if (equipSlot && | |
item is IArmsItem arms) | |
{ | |
equipSlot.Equip(arms); | |
} | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment