0
\$\begingroup\$

I want to make a simple drag and drop system in 2D in Unity.

When the user drags the object to a position, I want to check if the position is valid. As in I want the user to drag an object onto another object with a specific tag of my choice. If it's anything other than that, the dragged object should return to its original position.

My problem is that my current code for detecting the object I've dropped onto always detects the object I dragged instead. How can I modify this code to detect the object under it?

// The plane the object is currently being dragged on
Plane dragPlane;

// The difference between where the mouse is on the drag plane and 
// where the origin of the object is on the drag plane
Vector3 offset;

Camera myMainCamera;

Vector3 originalPos;


void Start()
{
    myMainCamera = Camera.main;
    Physics2D.queriesStartInColliders = false;
    originalPos = gameObject.transform.position;
}

void OnMouseDown()
{
    collideCheck = false;
    dragPlane = new Plane(myMainCamera.transform.forward, transform.position);
    Ray camRay = myMainCamera.ScreenPointToRay(Input.mousePosition);
   
    float planeDist;
    dragPlane.Raycast(camRay, out planeDist);
    offset = transform.position - camRay.GetPoint(planeDist);
}

void OnMouseDrag()
{
    Ray camRay = myMainCamera.ScreenPointToRay(Input.mousePosition);

    float planeDist;
    dragPlane.Raycast(camRay, out planeDist);
    transform.position = camRay.GetPoint(planeDist) + offset;
}


private void OnMouseUp()
{
    //check if there is something at that position
    Collider2D hitColliders = 
    Physics2D.OverlapCircle(transform.position, range); 

    Debug.log(hitColliders);
    if (hitColliders.gameObject.tag == "p1") 
    { transform.parent = hitColliders.gameObject.transform; }
    else 
    { transform.position = originalPos; } 
}

private void OnDrawGizmosSelected()
{
    Gizmos.color = Color.red;
    //Use the same vars you use to draw your Overlap SPhere to draw your Wire Sphere.
    Gizmos.DrawWireSphere(transform.position, 1);
}
\$\endgroup\$
2
  • \$\begingroup\$ Did you perhaps intend to use a layer mask to exclude the dragged object from the query, or use OverlapCircleAll / OverlapCircleNonAlloc to inspect multiple colliders nearby? \$\endgroup\$
    – DMGregory
    Commented Sep 5, 2021 at 16:37
  • \$\begingroup\$ Solved the issue. \$\endgroup\$
    – Nomi
    Commented Sep 5, 2021 at 16:43

2 Answers 2

0
\$\begingroup\$

Use OverlapCircleAll to detect not just the dragged object's collider, but ALL colliders overlapping the circle, then check whether one of them has the target tag.

    Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, range);
    foreach (Collider2D hit in hitColliders)
    {
        if (hit.gameObject.tag == "objectTaghere")
        {
            check = true;
            if (check)
            {
                transform.parent = hit.gameObject.transform;
            }
            break;
        }
    }

    if (!check)
    {
        transform.position = originalPos;
    }
\$\endgroup\$
1
  • \$\begingroup\$ Please add further details to expand on your answer, such as working code or documentation citations. \$\endgroup\$
    – Community Bot
    Commented Sep 5, 2021 at 17:15
0
\$\begingroup\$

Note that you can write the code from your answer much more cleanly as:

void OnMouseUp() {
    foreach (var hit in Physics2D.OverlapCircleAll(transform.position, range))
    {
        // "CompareTag" is more efficient than "tag =="
        if (hit.CompareTag("objectTaghere"))
        {
            transform.parent = hit.gameObject.transform;
            return;
        }
    }
    
    // We can get here only if no match was found.
    transform.position = originalPos;
}

No extra "check" variable needed.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .