Unity 2D Raycast from mouse to screen

Discussion in '2D' started by Sinron, Nov 18, 2013.

  1. Sinron

    Sinron

    New Member

    Joined:
    Oct 12, 2012
    Messages:
    16
    So in 4.2 I had Screencast working where i could cast a ray from my mouse out into the scene and get an objects position if i hit it. NOW things have changed since I'm switching to Physics 2D because it's a 2D game. Come to find out old raycast don't work on 2D colliders and i cannot for the life of me figure out how I'm going to get the position of an object that my mouse is over when an event is triggered.

    I'm avoiding using OnMouseOver on objects because this is going to be a random thing that is controlled 100% by the player.
    Below is a sample of my code i'm attempting to use and it's not even close to working.

    Code (csharp):
    1.     /// <summary>
    2.     /// Cast a ray from the mouse to the target object
    3.     /// Then sets the target position of the ability to that object.
    4.     /// </summary>
    5.     public void ScreenMouseRay()
    6.     {
    7.         mousePosition.z = Mathf.Infinity;
    8.  
    9.         //RaycastHit2D hit = Physics2D.Raycast(Input.mousePosition ,Vector2.zero,Mathf.Infinity); //Hit object that contains gameobject Information
    10.  
    11.         if(hit)
    12.         {
    13.             //Debug.Log("Ray has been Cast and hit an Object");
    14.             targetPos = hit.collider.gameObject.transform.position; //Save the position of the object mouse was over
    15.             Debug.Log ("Target Position: " + targetPos);
    16.        
    After i get a raycast from mouse to object my goal is to use the targets position as the end destination for a ray going from the player to that target.
  2. JohnGallet

    JohnGallet

    New Member

    Joined:
    Sep 27, 2013
    Messages:
    12
    + 1 on this problem, I have the same problem here.

    It seems that to click on an object in 2D to select it for example is a lot more complicated than it should be!!!

    How I can click on the screen and get the tag of a gameObject for example. The old Camera.main.ScreenPointToRay(Input.mousePosition) is not working anymore with the new 2D physics.
  3. mrsquare

    mrsquare

    Member

    Joined:
    Oct 25, 2013
    Messages:
    116
    See this thread:

    http://forum.unity3d.com/threads/210960-Raycast-with-sprites

    But basically, if you just want to click the mouse directly on an object and have the raycast hit it, this should work:

    Code (csharp):
    1.  
    2.  
    3. if(hit.collider != null)
    4. {
    5.     Debug.Log ("Target Position: " + hit.collider.gameObject.transform.position);
    6. }
    7.  
    The Raycast point needs to be in world coordinates, and setting a distance vector of zero means that it will only intersect with the object immediately under the cursor.
    Last edited: Nov 18, 2013
  4. Sinron

    Sinron

    New Member

    Joined:
    Oct 12, 2012
    Messages:
    16
    Thanks for the reply mrsquare I'll have to give this a Shot when i get home.
  5. Sinron

    Sinron

    New Member

    Joined:
    Oct 12, 2012
    Messages:
    16
    So it seems this is always casting the ray from the camera straight down and since the camera follows the player that's all it hits. Essentially it doesn't seem to be taking the position of the mouse into consideration at all.
    Last edited: Nov 19, 2013
  6. Sinron

    Sinron

    New Member

    Joined:
    Oct 12, 2012
    Messages:
    16
    Here is the solution we came too.

    Code (csharp):
    1.     /// <summary>
    2.     /// Cast a ray from the mouse to the target object
    3.     /// Then sets the target position of the ability to that object.
    4.     /// </summary>
    5.     public void ScreenMouseRay()
    6.     {
    7.         mousePosition.z = 5f;
    8.  
    9.  
    10.         Collider2D[] col = Physics2D.OverlapPointAll(v);
    11.  
    12.         if(col.Length > 0){
    13.             foreach(Collider2D c in col)
    14.             {
    15.                 //Debug.Log("Collided with: " + c.collider2D.gameObject.name);
    16.                 targetPos = c.collider2D.gameObject.transform.position;
    17.             }
    18.         }
    19.     }
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Messages:
    122
    Raycast/Linecast for 2D take Vector2 not Vector3 because they operate along the X/Y plane only as it's 2D physics not 3D.

    There is however specialized calls that do take a Ray type for people that want to use 2D colliders in a pseudo 3D context. These calls are "GetRayIntersection", "GetRayIntersectionAll" and "GetRayIntersectionNonAlloc" and do what the say, find an intersection of a 3D ray on a 2D collider. Note that these calls will purposely return nothing if your ray is cast along the X/Y plane itself as 2D colliders are infinitely thin so you must always cast your ray along the Z axis at some angle.

    Internally what these calls do are project the ray start/end points into the Box 2D collider space, perform a standard line-cast in 2D space to find which 2D colliders are hit then calculate using back-projection where on those colliders the ray intersects given the transform Z of the GameObject. All returned colliders are sorted based upon the direction of the ray along the Z axis i.e. front-to-back or back-to-front. This will also calculate an appropriate hit normal.

    In other words, use the ray-intersection calls to find RaycastHit2D(s) in 3D space for 2D colliders.

    Hope this helps.
  8. Sinron

    Sinron

    New Member

    Joined:
    Oct 12, 2012
    Messages:
    16
    Great tips MelvMay thanks a bunch!