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.
/// <summary>
/// Cast a ray from the mouse to the target object
/// Then sets the target position of the ability to that object.
/// </summary>
public void ScreenMouseRay()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = Mathf.Infinity;
//RaycastHit2D hit = Physics2D.Raycast(Input.mousePosition ,Vector2.zero,Mathf.Infinity); //Hit object that contains gameobject Information
RaycastHit2D hit = Physics2D.Raycast(mousePosition, mousePosition - Camera.main.ScreenToWorldPoint(mousePosition),Mathf.Infinity);
Debug.DrawRay(mousePosition, mousePosition - Camera.main.ScreenToWorldPoint(mousePosition),Color.blue);
if(hit)
{
//Debug.Log("Ray has been Cast and hit an Object");
targetPos = hit.collider.gameObject.transform.position; //Save the position of the object mouse was over
Debug.Log ("Target Position: " + targetPos);
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.
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.
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.
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.
/// <summary>
/// Cast a ray from the mouse to the target object
/// Then sets the target position of the ability to that object.
/// </summary>
public void ScreenMouseRay()
{
Vector3 mousePosition = Input.mousePosition;
mousePosition.z = 5f;
Vector2 v = Camera.main.ScreenToWorldPoint(mousePosition);
Collider2D[] col = Physics2D.OverlapPointAll(v);
if(col.Length > 0){
foreach(Collider2D c in col)
{
//Debug.Log("Collided with: " + c.collider2D.gameObject.name);
targetPos = c.collider2D.gameObject.transform.position;
}
}
}
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.
FWIW, I find it supremely odd, and frustrating, that the Unity API chooses to have all 18 versions of Physics.Raycast() returns a bool, but none of the 8 versions of Physics2D.Raycast() returns a bool.
I think it would have been nice to be harmonious in this way.
For the record, to check for colliders under the mouse position, use Physics2D.OverlapPoint because this is 2D physics, not 3D physics. If you don’t need specifically to deal with a pseudo 3D ray. OverlapPoint is much faster too.
Sorry to say but that’s completely incorrect. Not only does this thread not relate to checking if a 1x1 box overlaps at the mouse position but “Input.mousePosition” is in screen-space so would need converting to world-space.
As I said previously, OverlapPoint is how you’d do it in 2D.