Search Unity

How To Stop Dragging By Script

Discussion in 'Scripting' started by brkbkc, Apr 15, 2019.

  1. brkbkc

    brkbkc

    Joined:
    Jan 28, 2019
    Posts:
    36
    Hello, I am developing a card game and using IBeginDragHandler, IDragHandler, IEndDragHandler. Everything is ok but there is a time limit which allows player to get a card from the deck. If player drag and drop in that limited time there is no problem. If player holds the card dragging and if the time is over, how can I stop dragging and throw card to deck back? I tried destroying and creating the card but it causes some problems. Some Coroutines do not work if i do it.
    Thanks
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Presumably, right now, you have a script somewhere that says something like "while the player is dragging, move the card to follow the pointer". Edit that script so that it checks whether the time limit has expired, and if it has, then instead of following the pointer, put the card back where it started.
     
  3. brkbkc

    brkbkc

    Joined:
    Jan 28, 2019
    Posts:
    36
    Thanks for suggestion. Yes, there is a command line like you said. I changed the line according the to your suggestion.
    I added a bool. If the time is over bool changes and card turns parent back but there is still problem.
    This is an online game, so I have to run app in an emulator and cant get debug logs. For this reason I cant understand where the problem is. I think that There is a conflict between countdown coroutine and IDraghandler-eventData.
    I think the solution is to clean(null) data in eventData, but i dont know how to do it. I tried this "OnDrag(null);" but no success.
     
  4. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    Why don't you build a debug version and at least put out your debug log into a textfield or textfile? Also why isn't it working out of Unity, should do or not? :)
     
  5. iMobCoding

    iMobCoding

    Joined:
    Feb 13, 2017
    Posts:
    165
    This is how I do it - made a public method which I can call to cancel a drag:

    Code (CSharp):
    1. {
    2.     private PointerEventData _lastPointerData;
    3.  
    4.     public void OnBeginDrag (PointerEventData eventData)
    5.     {
    6.         _lastPointerData = eventData;
    7.     }
    8.  
    9.     public void OnDrag (PointerEventData eventData)
    10.     {
    11.         // Set position here
    12.     }
    13.  
    14.     public void OnEndDrag (PointerEventData eventData)
    15.     {
    16.         _lastPointerData = null;
    17.      
    18.         // Reset position here
    19.     }
    20.  
    21.     public void CancelDrag ()
    22.     {
    23.         if (_lastPointerData != null)
    24.         {
    25.             _lastPointerData.pointerDrag = null;
    26.          
    27.             // Reset position here
    28.         }
    29.     }
    30. }
     
  6. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    Have your Card implement ISelectHandler and IDeselectHandler. and then in OnDeselect...
    Code (CSharp):
    1.         public void OnDeselect(BaseEventData eventData)
    2.         {
    3.             var pointerData = eventData as PointerEventData;
    4.             if(pointerData != null)
    5.             {
    6.                 // if I'm being dragged, change the event data to say I'm no longer dragged
    7.                 if(pointerData.pointerDrag == gameObject)
    8.                 {
    9.                     // This should automatically trigger EndDrag for this card,
    10.                     // OnDrop for any hovered slot, etc.
    11.                     pointerData.pointerDrag = null;
    12.                 }
    13.             }
    14.             else
    15.             {
    16.                 //have to manually reset card
    17.             }
    18.         }

    Then the script that is handling the timer can simply call something like
    Code (CSharp):
    1.  
    2.         private void HandleTimeOut()
    3.         {
    4.             //if any card was selected deselect that card
    5.             EventSystem.current.SetSelectedGameObject(null);
    6.         }
    this way other scripts can trigger a card to clean up its state without explicitly having to know about that card, and the card itself doesn't explicitly have to know about the rules for WHEN it should stop being dragged.
     
    razamgar likes this.
  7. brkbkc

    brkbkc

    Joined:
    Jan 28, 2019
    Posts:
    36
    Thanks all, I tried all suggestions. But no succesful result.
    JoshuaMcKenzie your idea looks as closest way but doesnt work (or i couldnt do it).
    1- I implemented both ISelectHandler and IDeselectHanler then put a text into them for controlling the method works. The texts are not changed in both side.
    2- I added this "EventSystem.current.SetSelectedGameObject(gameObject, eventData);" to IBeginDrag then ISelectHandler worked but OnDeselect It still doesnt work.

    With these methods I can reach BaseEventData, but I think i have to reach PointerEventData which is hold by EventSystem.

    Sorry for my confusion and my English.
     
  8. NullSave

    NullSave

    Joined:
    Oct 23, 2018
    Posts:
    5
    I know it's very late but you can set:
    Code (CSharp):
    1. eventData.pointerDrag = null;