Search Unity

Raycast with sprites

Discussion in '2D' started by Gesh, Nov 14, 2013.

  1. Gesh

    Gesh

    Joined:
    Feb 23, 2013
    Posts:
    6
    Hello, I have a sprite gameobject which is a ball, I want to detect when the player clicks on the ball.

    I have tried
    Code (csharp):
    1. RaycastHit hitInfo = new RaycastHit();
    2.         if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo))
    3.         {
    4.             Debug.Log( hitInfo.transform.gameObject.name );
    5.         }
    6.  
    but the ball does not get detected at all.. I have added 3D objects to my scene to test it and it works for 3D objects fine..

    Does anyone have any idea on what's wrong?
    Thanks.
     
  2. Lukas H

    Lukas H

    Joined:
    Jan 16, 2009
    Posts:
    394
    Use Physics2D.Raycast ;)
     
  3. Gesh

    Gesh

    Joined:
    Feb 23, 2013
    Posts:
    6
    Ahhh! thank you:)
     
  4. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    And be sure to use RaycastHit2D.
     
  5. okankoc83

    okankoc83

    Joined:
    Jun 13, 2013
    Posts:
    1
    Hey all

    i changed "Physics.Raycast" to "Physics2D.Raycast" and "RaycastHit" to "RaycastHit2D"
    Like that:
    Code (csharp):
    1. RaycastHit2D hitInfo = new RaycastHit2D();
    2.        
    3.   if (Physics2D.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo)){
    4.                
    5.      Debug.Log( hitInfo.transform.gameObject.name );
    6.            
    7.   }
    but i get these errors:

    "error CS1502: The best overloaded method match for `UnityEngine.Physics2D.Raycast(UnityEngine.Vector2, UnityEngine.Vector2)' has some invalid arguments"

    and

    "
    Code (csharp):
    1. error CS1503: Argument `#1' cannot convert `UnityEngine.Ray' expression to type `UnityEngine.Vector2'"
    2.  
    3. Where do i make mistake?
     
  6. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    Does the OnMouseDown function work on your ball? Seems this way would be easier for your needs.
     
  7. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    You need to pass a Vector2 as the first argument, not a Ray, the second argument should be a Vector2, and the RayCastHit2D is returned by the function. Looks like you've just got a bit confused between the Physics.Raycast and Physics2D.Raycast syntax. Try this:

    Code (csharp):
    1.  
    2. RaycastHit2D hitInfo = Physics2D.Raycast(mouseWorldPosition, Vector2.zero);
    3.  
    4. if(hitInfo != null)
    5. {
    6.     Debug.Log( hitInfo.rigidbody.gameObject.name );
    7. }
    8.  
     
    Last edited: Nov 18, 2013
    Seiktate and konsul300 like this.
  8. infinitypbr

    infinitypbr

    Joined:
    Nov 28, 2012
    Posts:
    3,149
    Ah this thread just solved my issue with the ray cast as well!
     
  9. JohnGallet

    JohnGallet

    Joined:
    Sep 27, 2013
    Posts:
    16
    Not working....
    In JS

    gives this error:

    BCE0023: No appropriate version of 'UnityEngine.Physics2D.Raycast' for the argument list '(UnityEngine.Vector3, UnityEngine.RaycastHit2D)' was found.
     
  10. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Sorry, my bad, wrote that reply without actually compiling it - I've amended my original answer with the correct C# script. For Javascript, try:

    Code (csharp):
    1.  
    2. if (Input.GetMouseButtonDown(1))
    3. {
    4.     var hit : RaycastHit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    5.  
    6.     if(hit.collider != null)
    7.     {
    8.         Debug.Log("object clicked: "+hit.collider.tag);
    9.     }
    10. }
    11.  
    This is basically 2D ray casting with a vector of size zero, which will collide with the object immediately underneath the cursor position.
     
    Last edited: Nov 18, 2013
    Robert_Allen likes this.
  11. JohnGallet

    JohnGallet

    Joined:
    Sep 27, 2013
    Posts:
    16
    For some reason it is still doing an error. Here is the full code

    Code (csharp):
    1.  
    2. #pragma strict
    3. function Start () {
    4. }
    5.  
    6. function Update () {
    7.     if (Input.GetMouseButtonDown(1))
    8.     {
    9.         var hit : RaycastHit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    10.         if(hit != null)
    11.         {
    12.             Debug.Log("object clicked: "+hit.collider.tag);
    13.         }
    14.     }
    15. }
    This is making :NullReferenceException: Object reference not set to an instance of an object
    Global.Update () (at Assets/Scripts/Global.js : 8 )

    I have tried to make the camera public like this

    Changed the hit with

    And drag and drop the camera in the public slot, but got the same error :eek:

    Is it only me? Why this code would make an error?
     
  12. JohnGallet

    JohnGallet

    Joined:
    Sep 27, 2013
    Posts:
    16
    Oups working! I made a mistake in the last post. Here is the working script, hopefully it will help someone!
    (not forget to drag and drop the active camera in the camera public slot of the script.)

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. public var cam:Camera;
    5. function Start () {
    6. }
    7.  
    8. function Update () {
    9.     if (Input.GetMouseButtonDown(1))
    10.     {
    11.         var hit : RaycastHit2D = Physics2D.Raycast(cam.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    12.         if(hit != null)
    13.         {
    14.             Debug.Log("object clicked: "+hit.collider.tag);
    15.         }
    16.     }
    17. }
    18.  
     
    sivasu likes this.
  13. mrsquare

    mrsquare

    Joined:
    Oct 25, 2013
    Posts:
    281
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. function Start ()
    5. {
    6. }
    7.  
    8. function Update ()
    9. {
    10.     if (Input.GetMouseButtonDown(1))
    11.     {
    12.         var hit : RaycastHit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    13.  
    14.         if(hit.collider != null)
    15.         {
    16.             Debug.Log("object clicked: "+hit.collider.tag);
    17.         }
    18.     }
    19. }
    20.  
    Seems that hit the 'hit' variable returned by the function is always valid, but you need to check that the collider is non-null

    *edit* And you need a valid main camera, of course, as noted above :)
     
    Last edited: Nov 18, 2013
    taeseong_park likes this.
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,497
    RaycastHit2D is a struct therefore you won't get a NULL returned but as mentioned the collider will be valid or NULL. However, to save you from having to perform the ugly explicit check whether the collider is null or not, RaycastHit2D has an implicit conversion operator to bool so you can do:

    Code (csharp):
    1.  
    2. if (hit)
    3. {
    4.    ...
    5. }
    6.  
     
  15. Occma

    Occma

    Joined:
    Aug 15, 2013
    Posts:
    1
    hello, i seem to have the same problem. I tried to copy this solutions but i doesn't work for some reason.

    Code (CSharp):
    1.     void Update ()
    2.     {
    3.         if (m_turn == TurnState.PlayerInput)
    4.         {
    5.             if (Input.GetButtonDown("Fire1"))
    6.             {
    7.                 Debug.Log(m_ray.OnMouseClick2D());
    8.             }  
    9.         }
    10. }
    11.  
    12.   public RaycastHit2D m_hit2D;
    13.  
    14. public GameObject OnMouseClick2D(params int[] _mask)
    15.     {
    16.  
    17.         //m_ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    18.         foreach (int mask in _mask)
    19.         {
    20.             m_hit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition) , Vector2.zero, 1000.0f, 1 << mask);
    21.             if (m_hit2D.collider != null)
    22.             {
    23.                 return m_hit2D.transform.gameObject;
    24.             }
    25.         }
    26.         m_hit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition) , Vector2.zero);
    27.         if (m_hit2D.collider != null)
    28.         {
    29.             return m_hit2D.transform.gameObject;
    30.         }
    31.         return null;
    32.     }
    My scene is full of Sprites, but i allways get null.
    Some guesses?
     
    OceanBlue likes this.
  16. ama7520

    ama7520

    Joined:
    Jun 13, 2015
    Posts:
    2
    i have this script and didn't find any error on it, but when i play it the door wasn't open, please help me question.png
     
  17. ryanmillerca

    ryanmillerca

    Joined:
    Aug 12, 2012
    Posts:
    143
    This appears to work with orthographic cameras but not perspective. Seems like 2D Raycasts using ScreenToWorldPoint don't support perspective cameras!

    Try GetRayIntersection and ScreenPointToRay instead.
    Code (CSharp):
    1. RaycastHit2D rayHit = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay(Input.mousePosition));
     
  18. krupps

    krupps

    Joined:
    Oct 17, 2017
    Posts:
    159
    For anyone seeing this, change the MouseDown to 0 for the left button