2015-01-28 6 views
7

Mam skrypt, który obsługuje przeciąganie elementów zi do danego gniazda. Ale chcę dodać funkcję, aby zatrzymać przeciąganie określonych elementów. Myślę, że najlepszym miejscem do zrobienia jest w metodzie OnBeginDrag, ale cant wydają się zrozumieć sposób, aby zatrzymać/anulować samej imprezy oporu, tutaj jest nieco mojego kodujak zatrzymać zdarzenie przeciągania w OnBeginDrag() w jedności 4.6

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]); 
      } 
     } 
    } 
} 

Próbowałem powrocie metodę wcześniej, ale to nic nie robi, prawdopodobnie trzeba coś zrobić z danymi o wydarzeniach ... Będę wdzięczny, jeśli powiesz mi, jak sobie z tym poradzić.

+0

UWAGA - oto niezwykle pełny, elegancki, roztwór do drag/drop .. cieszyć http://stackoverflow.com/a/37473953/294884 – Fattie

Odpowiedz

2

Możesz utworzyć flagę (na przykład IsDragable). Dla pozycji które donn't chcą przeciągnąć & spadek trzeba powrócić z obsługi zdarzeń przeciągania:

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 
} 

Innym rozwiązaniem jest wyłączenie BlockRaycast w CanvasGroup komponentu.

+0

dobrze, że to co ja robi.Ale tak naprawdę nie zatrzymuje on obiektu OnDrag i zdarzeń OnEndDrag. lub OnDrop (wywołany w miejscu docelowym). –

+0

Nie ma problemu tutaj. Możesz sprawdzić flagę IsDraggable w zdarzeniu OnDrop. I nie rób nic, jeśli jest fałszywy. – acoolaum

+0

Dziękujemy! Bardzo podoba mi się BlockRaycast, ponieważ wyłącza to również wszystkie wyzwalacze (takie jak animacje), które zależą od zdarzenia Drag dla tego GameObject, podczas gdy DragHandler nie pomaga w wyłączaniu zdarzeń i wyzwala wyzwalanie (odtwarzanie animacji). – Qorbani

12

Samo użycie "return" nic nie anuluje.

Zamiast tego można zmodyfikować informacje PointerEventData przekazane do funkcji OnBeginDrag - w szczególności ustawić parametr pointerDrag na wartość null. To anulować Przeciąganie:

eventData.pointerDrag = null; 
+1

To powinno być oznaczone jako poprawna odpowiedź. Druga sugestia dotycząca powrotu z metody zdarzenia jest dziecinna! – Xtro

+0

Ta odpowiedź została wysłana dokładnie dwa lata po zaakceptowanej odpowiedzi, ale jest to właściwie poprawna odpowiedź. Jak już wspomniano, ustawienie 'pointerDrag' na' null' w rzeczywistości zapobiega nawet podniesieniu zdarzeń OnDrag i OnEndDrag. Dzięki! –

Powiązane problemy