Hi all,
I have a background (GameObject) and multiple (actionObjects) GameObject passing by. The player can tap either on the background itself (triggering some action) or on one of the actionObjects (triggering other action)
Right now, the tap/click goes through the gameobject and it’s always the background getting the click.
I’m using
if (Input.GetKeyDown(KeyCode.Mouse0))
{
if (GameManager.instance.gameStatus == "W" && EventSystem.current.IsPointerOverGameObject())
{
do something
}
}
also tried with
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Ray ray = Camera.main.GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
print("********** HIT HIT HIT HIT>" + hit.collider.gameObject.name);
}
but it’s always the background getting the hit, not the GameObject despite being on a higher z
is there a simple way to know where the player has tapped/clicked and to avoid the event to be passed further down to the background ?
thanks
Hello.
You should tell your Raycast to identify what it’s clicking on. The simplest way would be using a Layer Mask:
Ray ray = mainCam.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray.origin, ray.direction * 10, out hitInfo, Mathf.Infinity, selectableLayerMask))
{
objectSelected = hitInfo.collider.gameObject;
}
I’m not sure i understand, while they can be on different layers, background & gameObjects can be clicked at anytime.
Also are you saying I should have one layer for the background and one for each game object ?
Please note that this is the 2D forum and your post doesn’t relate at all to 2D features. It’s 3D physics and Input.
Maybe you’re expecting to use 2D physics and this is your problem?
oh sorry, I am definitely doing a 2d game and just want to know where the player has clicked/tapped.
I found the raycast code in the middle of 600 hundred posts and trying to get this to work a way or another.
Coming from Corona2D where it’s a one line code, i never imagine it would be that complicated to do in Unity.
If you have a solution (simple if possible) for a 2D game to know what object has been clicked, please please share
Okay so you don’t mention it but a GameObject doesn’t have any concept of area, it’s just a container of components. When you want to know if your mouse has clicked on it, you need something to detect. You can use 2D physics colliders so you can, for instance, add a BoxCollider2D. You can then use a simple 2D physics query like Physics2D.OverlapPoint which will tell you what collider overlaps that world-point or it’ll return NULL if nothing is there. Typically Camera.ScreenToWorldPoint is used to convert the mouse point to a world-point. There’s lots of overloads for queries that allow you to return things like a single collider or multiple ones etc.
1 Like
thank you Melv, things happen when someone explains in simple terms.
here if the code if someone is interested.
to be inserted in any of the update class but probably ideally in the GameManager update()
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Vector3 wp = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var touchPos = new Vector2(wp.x, wp.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if (hit != null)
{
if (EventSystem.current.IsPointerOverGameObject())
// means it's over a UI gameObject not a 'normal' game object.. ! ..
{
//print ("HIT HIT IsPointerOverGameObject=true .. its over a UI element");
return; // will let the onclick of the UI do its job
}
else
{
//print("HIT HIT IsPointerOverGameObject=false its over a REAL=nonUI gameobject");
GD.realGameObjectClicked = true;
}
print("HIT HIT HIT on >" + hit.gameObject.name + "<>" + hit.tag);
if (hit.tag == "redcar")
{
do_something_with_the_red_car()
return()
}
}
}
1 Like
Hi!
I have used your code inside the touch control for android and I am stuck on a situation where it either always returns from “UI Hit” no matter if there is a UI element overlayed or not. Same if I negate whole event system condition, it then returns always with a hit of an underlying game object.
It seems that no matter what I do, it registers only the game object underneath (sprite with collider) and not the UI on top. I keep getting desparate as I have tried many different codes and nothing works and raycast and others just pass through UI. Do you see any mistake in the code perhaps?
else if (Mathf.Abs(lp.x - fp.x) < dragDistance || Mathf.Abs(lp.y - fp.y) > dragDistance)
{ //It's a tap as the drag distance is less than 20% of the screen height
Debug.Log("Tap");
Vector3 wp = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
var touchPos = new Vector2(wp.x, wp.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if (hit != null)
{
Debug.Log("We have a hit!");
if (!EventSystem.current.IsPointerOverGameObject())
// means it's over a UI gameObject not a 'normal' game object.. ! ..
{
Debug.Log("...but it was UI!!!");
//print ("HIT HIT IsPointerOverGameObject=true .. its over a UI element");
return; // will let the onclick of the UI do its job
}
else
{
Debug.Log("...not UI after all.");
}
Debug.Log("We hit: " + hit.gameObject.name);
}
else
{
Debug.Log("Did not hit anything!");
}
}
Any possible help would be highly appreciated. Thanks!