7
\$\begingroup\$

I'm creating a 2D project which does not have a character. So I created an empty game object and attached a script to it. In the script, I have declared other objects which are in the scene like this:

public GameObject obj1,obj2,obj3;

How can I know if obj1 or obj2 or obj3 was clicked? Is raycasting the only solution?

\$\endgroup\$

4 Answers 4

12
\$\begingroup\$

Yes, you can use raycasting to detect the objects in your scene. You don't need to attach a custom script to the game objects you want to detect, but you do need to attach colliders to them.

In the update method of your script, attached to the otherwise empty object, you can check for when the mouse button is pressed. Then, cast a ray into the scene from the camera, through the mouse. Something like the following:

void Update() {
    if (Input.GetMouseButtonDown(0)) {
        Debug.Log("Pressed left click, casting ray.");
        CastRay();
    }
}

void CastRay() {
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100)) {
        Debug.DrawLine(ray.origin, hit.point);
        Debug.Log("Hit object: " + hit.collider.gameobject.name);
    }
}
\$\endgroup\$
6
  • \$\begingroup\$ Thanks. The first Debug line is printed to console. Then i get this: UnityEngine.Debug:Log(Object). But the last Debug line is not shown. \$\endgroup\$
    – SanSolo
    Sep 4, 2014 at 14:33
  • \$\begingroup\$ Also, the raycast is firing when i click my GUI buttons too. Is that a problem? \$\endgroup\$
    – SanSolo
    Sep 4, 2014 at 14:39
  • \$\begingroup\$ Read the documentation on raycasting. You need to add colliders to the objects you want to be detected with the ray. Yes, the ray will be cast any time you press the mouse button, that includes when pressing for GUI items, you'll need to detect separately when clicking a GUI item and not allow the raycast in those situations. That's an entirely different question though and not suitable to be addressed in the comments of this answer. \$\endgroup\$
    – House
    Sep 4, 2014 at 14:50
  • \$\begingroup\$ Yes I added BoxCollider2D to the object. Object name is not shown in the console. \$\endgroup\$
    – SanSolo
    Sep 4, 2014 at 14:55
  • \$\begingroup\$ If it's a 2D collider, you need the 2D raycast. \$\endgroup\$
    – House
    Sep 4, 2014 at 15:23
5
\$\begingroup\$

I modified the script and now it works. First, I remove:

public GameObject obj1, obj2, obj3; // Although this shouldn't affect the script.

The updated script is as follows:

using UnityEngine;
using System.Collections;

public class ClickTest : MonoBehaviour {
    // public GameObject red, red2, yellow, yellow2, MainCamera;
    // Use this for initialization

    void Start () {
    }

    // Update is called once per frame
    void Update () {
            if (Input.GetMouseButtonDown(0)) {
            Debug.Log("Pressed left click, casting ray.");
            CastRay();
        }       
    }

    void CastRay() {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast (ray.origin, ray.direction, Mathf.Infinity);
        if (hit) {
            Debug.Log (hit.collider.gameObject.name);
        }
    }    
}
\$\endgroup\$
0
\$\begingroup\$

I Still Believe that part of this question was not answered. The part

Is raycasting the only solution?

Well its not the only solution there is also:

void OnMouseDown(){
    Destroy(gameObject);
}

Attach that script to the target object i.e. the one that wants to register the mouse clicks.

\$\endgroup\$
3
  • \$\begingroup\$ Actually can't use OnMouseDown() as I have many objects and attaching the script to each of them is not feasible \$\endgroup\$
    – SanSolo
    Mar 1, 2016 at 9:36
  • \$\begingroup\$ Oh Ok... that would be overkill. BUt i wanted to prove that raycasting is not the ONLY solution as had been asked. Also you could do a foreach on the gameObjects and add the script using gameObject.AddComponent<MyScript>() \$\endgroup\$
    – S. McGrady
    Mar 1, 2016 at 12:39
  • \$\begingroup\$ Yes adding component by having an array is a possibility. But there would be more issues. For example, I don't just want to know if the object was clicked. I want to do something with that information. For example, change the clicked objects color. Considering all the things, raycasting remained the best solution. \$\endgroup\$
    – SanSolo
    Mar 1, 2016 at 12:49
0
\$\begingroup\$

If you set up an edge collider on the objects you can use:

void Update()
{
    //this detects the mouse position
    Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    //this check to see if the mouse is over the collider documentation below
    if (this.GetComponent<EdgeCollider2D>().ClosestPoint(mousePos) == mousePos)
    {
         print("mouse is hovering over object");
         if(Input.GetKeyDown(KeyCode.Mouse0))
         {
             print("mouse clicked on object");
         }
    }
 }

For more information, refer to the documentation for Collider.ClosestPoint.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .