Search Unity

Question How to use Unity Physics Engine when using IDragHandler

Discussion in '2D' started by DragoRyu2001, Jul 2, 2020.

  1. DragoRyu2001

    DragoRyu2001

    Joined:
    Mar 24, 2020
    Posts:
    4
    Hey there,
    I am trying to make a game where the user drags and drops the text into the box.
    So for dragging what I did was used the IDragHandler to track the text to my mouse.
    However, whenever I am dragging the object it is unable to detect Collisions and I am unable to move forward.
    Any help will be appreciated
    Thanks in Advance.
    Here is my Script


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class DragandDrop : MonoBehaviour, IPointerDownHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
    7. {
    8.     [SerializeField] private Canvas canvas;
    9.     private RectTransform rectransform;
    10.     private CanvasGroup canvasGroup;
    11.     private Vector3 startPos;
    12.     private bool collided;
    13.  
    14.     private void Awake()
    15.     {
    16.         rectransform = GetComponent<RectTransform>();
    17.         canvasGroup = GetComponent<CanvasGroup>();
    18.         startPos = this.transform.localPosition;
    19.         collided = false;
    20.     }
    21.  
    22.     public void OnPointerDown(PointerEventData eventData)
    23.     {
    24.         Debug.Log("PointerDown");
    25.     }
    26.  
    27.     public void OnBeginDrag(PointerEventData eventData)
    28.     {
    29.         Debug.Log("BeginDragging");
    30.         canvasGroup.alpha = 0.5f;
    31.         canvasGroup.blocksRaycasts = false;
    32.     }
    33.  
    34.     public void OnDrag(PointerEventData eventData)
    35.     {
    36.         Debug.Log("Dragging");
    37.         rectransform.anchoredPosition += eventData.delta / canvas.scaleFactor;
    38.     }
    39.  
    40.     public void OnEndDrag(PointerEventData eventData)
    41.     {
    42.         Debug.Log("Stopped Dragging");
    43.         canvasGroup.alpha = 1f;
    44.         canvasGroup.blocksRaycasts = true;
    45.         if(!collided)
    46.         {
    47.             rectransform.anchoredPosition = startPos;
    48.         }
    49.     }
    50.     private void OnTriggerEnter2D(Collider2D collision)
    51.     {
    52.         collided = true;
    53.         Debug.Log("Collided with Something!!!!!");
    54.     }
    55.     private void OnTriggerExit2D(Collider2D collision)
    56.     {
    57.         collided = false;
    58.     }
    59.  
    60. }
    61.  
     
  2. Mooxe

    Mooxe

    Joined:
    Sep 18, 2013
    Posts:
    19
    Hey,

    I assume the objects you are trying to get the text to collide with, don't have "isTrigger" set to true.

    Try replacing OnTriggerEnter2D with OnCollisionEnter2D.
    and same with OnTriggerExit2D to OnCollisionExit2D


    Code (CSharp):
    1.  
    2.  private void OnCollisionEnter2D(Collider2D collision)
    3.     {
    4.         collided = true;
    5.         Debug.Log("Collided with Something!!!!!");
    6.     }
    7.     private void OnCollisionExit2D(Collider2D collision)
    8.     {
    9.         collided = false;
    10.     }
     
  3. DragoRyu2001

    DragoRyu2001

    Joined:
    Mar 24, 2020
    Posts:
    4
    Hi,
    Actually I just want to make a simple drag and drop with a text(the item) and an Image UI(The slot). So I just want the text to detect the Slot so that it does not reset to its original position as shown here:
    Code (CSharp):
    1. public void OnEndDrag(PointerEventData eventData)
    2.     {
    3.         Debug.Log("Stopped Dragging");
    4.         canvasGroup.alpha = 1f;
    5.         canvasGroup.blocksRaycasts = true;
    6.         if(!collided)
    7.         {
    8.             rectransform.anchoredPosition = startPos;
    9.         }
    10.     }
    Please feel free to drop your suggestions on how I can make it work, or am I taking it the wrong way.
    Thanks in advance.
     
  4. Mooxe

    Mooxe

    Joined:
    Sep 18, 2013
    Posts:
    19
    Yeah, for something like that, you would probably need another script on the Item Slot itself.
    an IDropHandler - https://docs.unity3d.com/2018.1/Documentation/ScriptReference/EventSystems.IDropHandler.html

    It allows you to check whether something has dropped on the object itself, so in this case, checks if the text dropped on the item slot.

    So if I were to put this script on the item slot,

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class DropMe : MonoBehaviour, IDropHandler
    6. {
    7.     public void OnDrop(PointerEventData data)
    8.     {
    9.         if (data.pointerDrag != null)
    10.         {
    11.             Debug.Log ("Dropped object was: "  + data.pointerDrag);
    12.         }
    13.     }
    14. }
    I'd replace Debug.log, with
    data.pointerDrag.GetComponent<RectTransform>().anchoredPosition = GetComponent<RectTransform>().anchoredPosition;


    So it sets the Object that was dropped on the ItemSlot to have the same position as the Item Slot.
    Hopefully this works.
     
  5. DragoRyu2001

    DragoRyu2001

    Joined:
    Mar 24, 2020
    Posts:
    4
    Hi,
    I tried to do add the IdropHandler in the Slot.
    The good news "It works", the bad news "Kinda".
    The text is dropping into the slot but afterwards, it is also going back to its original position.
    I know the reason to it is this
    Hi,
    I tried this method.
    The Good news: "It works"
    The Bad news: "Kinda"
    The issue that happens now is that whenever I put it into the slot it snaps to its centre of the slot but then it goes back to its original position(This happened so fast I could not see it but the debug.Log on each function showed me it was getting executed).
    Here is my code for the slot:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class DropSlot : MonoBehaviour, IDropHandler
    7. {
    8.     private CanvasGroup canvasGroup;
    9.     private bool collided, released, full;
    10.     private void Awake()
    11.     {
    12.         canvasGroup = GetComponent<CanvasGroup>();
    13.         full = false;
    14.     }
    15.     public void OnDrop(PointerEventData eventData)
    16.     {
    17.         if (!full)
    18.         {
    19.             Debug.Log("Droppped In Slot");
    20.             if (eventData.pointerDrag != null)
    21.             {
    22.                 eventData.pointerDrag.GetComponent<RectTransform>().anchoredPosition = GetComponent<RectTransform>().anchoredPosition;
    23.             }
    24.             full = true;
    25.         }
    26.     }
    27.  
    28.    
    29. }
    If I remove the reset position logic(present in the DragandDrop Script given originally) it works perfectly fine, but I kinda wanna have it there so that whenever it is placed outside the slot it snaps back to its original position. I thought of putting that logic in the slot but another issue that occurs is that there are multiple slots, so if one slot detects it then other slots will not and they will reset the Text.
    I am at a lost
    Please give your suggestions on how to improve it.
    Thanks in advance.
     
  6. Mooxe

    Mooxe

    Joined:
    Sep 18, 2013
    Posts:
    19
    Hello,
    I'm not sure if this is the right way to go but I think I have a cheat method to fix this.

    Create a new Image in your Canvas and call it Background or something - make it invisible (alpha = 0).
    Make this image bigger than your Screen size, and place it behind all your other UI Elements.

    On that, create another OnDrop Script, to check whether the Text is dropped onto this Background,
    If yes, then it should place the Text back onto the same position. (Reset position logic here)

    Now if text is dropped on the slot it should stay in the slot, and anywhere else, it would revert back to its original position.

    And you can now remove the Reset position logic from the DragandDrop script.

    Tell me if this method messes with some other functionality.
    Also, do tell me what you're trying to do here, is it a Scrabble game or something?

    Cheers,
     
    DragoRyu2001 likes this.
  7. DragoRyu2001

    DragoRyu2001

    Joined:
    Mar 24, 2020
    Posts:
    4
    Hi,
    IT WORKED!!!
    I made these reset zones and they properly reset the object back to its position. Thank you so much I was breaking my head over this for so long.
    Yeah, I am trying to make an educational game for children, where they put correct words in front of the picture. I am new to game development and facing a lot of obstacles.
    Again Thank you for your help.
    Regards,
    DragoRyu
     
  8. Mooxe

    Mooxe

    Joined:
    Sep 18, 2013
    Posts:
    19
    Hey, glad it works!

    I too have a lot to learn, just recently tried to make a 2d game like Realm of the Mad God, and had done some research on item slots.

    You're welcome :D