Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to determine what GameObjects are below a given mouse point (2D)

Discussion in '2D' started by ninelogic_technologies, Feb 6, 2020.

  1. ninelogic_technologies

    ninelogic_technologies

    Joined:
    Dec 11, 2016
    Posts:
    4
    I am trying to determine what game objects are at a given mouse point.

    UPDATE: It fails if I have UI Scale Model = Scale with Screen Size. Not sure why yet.

    This way, on drag drop, when my OnEndDrag() event is fired, I can see what game objects are at the mouse point when drag ended. This will allow me to determine if any valid containers are below the mouse point so I can add the object being dragged to it.

    I attached Box Collider 2D to my game objects. However, the RayCast always returns no hits at any mouse point.

    What must be done to get a hit?

    Here are the exact steps I took to test this:

    1. Create a new scene (2D)

    2. Add a Canvas

    3. Add Box Collider 2D to the canvas and make it as large as the canvas.

    4. Add a script to the scene and in Update() function show detect what objects are below the mouse point when mouse down is fired.
    The following are various techniques to try to get a hit. All fail.

    Code (CSharp):
    1. void Update()
    2.     {
    3.         if (Input.GetMouseButtonDown(0))
    4.         {
    5.             Debug.Log("Mouse down");
    6.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    7.             RaycastHit2D raycastHit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10)), Vector2.zero);
    8.             if (raycastHit)
    9.             {
    10.                 Debug.Log("Hit: " + raycastHit.transform.gameObject.name);
    11.             }
    12.  
    13.             Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    14.             RaycastHit2D hit = Physics2D.Raycast(mousePos, Vector2.zero);
    15.             if (hit.collider != null)
    16.             {
    17.                 Debug.Log(hit.collider.name);
    18.             }
    19.  
    20.             RaycastHit2D[] hits = Physics2D.GetRayIntersectionAll(ray, Mathf.Infinity);
    21.             Vector2 v = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    22.  
    23.             Collider2D[] c = Physics2D.OverlapPointAll(v);
    24.             if (c.Length > 0)
    25.             {
    26.                 Debug.Log("Hit!!!");
    27.             }
    28.  
    29.             RaycastHit2D[] allHits = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    30.             if (allHits.Length > 0)
    31.             {
    32.                 Debug.Log("Hit!!!");
    33.             }
    34.         }
    35.     }
     
    Last edited: Feb 6, 2020
  2. ninelogic_technologies

    ninelogic_technologies

    Joined:
    Dec 11, 2016
    Posts:
    4
    Figured it out.

    If you have your 2D canvas UI Scale Mode set to "Scale with Screen Size".

    Then use -Vector2.up for the direction:

    Code (CSharp):
    1. RaycastHit2D[] allHits = Physics2D.RaycastAll(Input.mousePosition, -Vector2.up);
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,623
    Don't use a degenerate 2D raycast to perform what is effectively a pseudo 3D raycast "into" the screen. Simply use OverlapPoint.
     
    NamelessGames_ likes this.