# Select 2D Object By Mouse ?

Hi …

I’m trying to make a 2D Game but I have this problem …

How can I select the character by clicking on it ?

Note :

• I’ve 3 Layers ( Background , Characters , Objects )
• In 3D game I can use ( ray , RaycastHit and Physics )
to do that , but I tried to convert it to 2D , but it doesn’t work …

Please how can I do that ?

2 Likes

This will return a 2D collider at the current mouse position. It works by calculating the 2D position of the mouse from the Orthographic camera. Then, doing a 2d raycast with a single point(zero length), but infinite depth(distance from camera). This works because Physics2D.Raycast() can return colliders that the ray begins inside.

Physics2D.Raycast(position, direction, length);

Here:

Physics2D.Raycast(new Vector2(camera.ScreenToWorldPoint(Input.mousePosition).x,camera.ScreenToWorldPoint(Input.mousePosition).y), Vector2.Zero, 0f);

[OLD]:
Don’t forgot to use Physics2D.Raycast().

There are three ways for you to solve your problem:

1. Use as script with an OnMouseDown() function attached to each selectable object. OnMouse* functions work with both 2D and 3D colliders.

2. Use a 3D collider on a child object. You cannot have a 2D and a 3D collider on the same object, but you can have an empty game object as a child of your sprite with its own collider. You’ll need to pick and size the collider as appropriate to your sprite. You can use the transform.parent of the child object if you need to get access to the sprite and/or its scripts. You would use the original Physics.Raycast().

3. Here is a hack I discovered yesterday. First convert your mouse position into a world coordinate using Camera.ScreenToWorldPoint(). Then use that position to do a Physics2D.Raycast() with a very short ray (like 0.05). It does matter what direction, but the distance needs to be short.

pseudo code

if (Input.GetMouseButtonDown(0) && myPlayerRect.Contains(Input.mousePosition))
{
//I've clicked on the player
}

This works for me by attaching the script to the main camera (Orthographic).
It is based on Spinnernicholas solution.

// Update is called once per frame
void Update () {

if (Input.GetMouseButtonDown(0))
{
Vector2 origin = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
RaycastHit2D hit = Physics2D.Raycast(origin, Vector2.zero, 0f);
if (hit) {
print(hit.transform.gameObject.tag);
}
}
}