2015-01-28 20 views
7

Ho uno script che gestisce il trascinamento di un oggetto da e verso un determinato slot. Ma voglio aggiungere una funzione per interrompere il trascinamento di elementi specifici. Credo che il posto migliore da fare è nel metodo OnBeginDrag, ma posso sembrare calcolare un modo per fermare/annullare l'evento di trascinamento stesso, ecco un po 'del mio codicecome interrompere l'evento di trascinamento in OnBeginDrag() nell'unità 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]); 
      } 
     } 
    } 
} 

ho cercato di restituire il metodo precedente, ma non fa nulla, probabilmente ha bisogno di fare qualcosa con i dati dell'evento ... sarò grato se mi dirai come affrontarlo.

+0

NOTA - qui è estremamente completa, un elegante soluzione per drag/drop .. preferisci http://stackoverflow.com/a/37473953/294884 – Fattie

risposta

2

È possibile creare un flag (ad esempio, IsDragable). Per gli elementi che si desidera trascinare donn't & goccia si deve tornare da gestori di eventi di trascinamento:

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 
} 

Altra soluzione è quella di disabilitare BlockRaycast in CanvasGroup componente.

+0

bene che è quello che sono doing.but in realtà non ferma gli eventi OnDrag e OnEndDrag dell'oggetto. o OnDrop (chiamato sulla destinazione). –

+0

Non c'è nessun problema qui. Puoi controllare il flag IsDraggable nell'evento OnDrop. E non fare nulla se è falso. – acoolaum

+0

Grazie! Mi piace l'approccio molto migliore di BlockRaycast poiché disabilita anche tutti i trigger (come le animazioni) che dipendono dall'evento Drag per quel GameObject, mentre DragHandler non sta aiutando la disattivazione degli eventi e attiva ancora gli attivatori (riproduzione di animazioni). – Qorbani

12

L'uso di "ritorno" non annulla nulla.

Invece, è possibile modificare le informazioni di PointerEventData passate nella funzione OnBeginDrag, in particolare, impostare pointerDrag su null. Ciò annulla la resistenza:

eventData.pointerDrag = null; 
+1

Questo dovrebbe essere contrassegnato come risposta corretta. L'altro suggerimento sul ritorno dal metodo dell'evento è infantile! – Xtro

+0

Questa risposta è stata pubblicata esattamente due anni dopo la risposta accettata, ma questa è in realtà la risposta corretta. Come detto, l'impostazione di 'pointerDrag' su' null' impedisce, in effetti, che gli eventi OnDrag e OnEndDrag vengano persino sollevati. Grazie! –