IPointerClickHandler doesn't work on unity game object - unity3d

I have unity 2D project and I wanted to detect left click event on the player game object.
I added Physics2DRaycaster to MainCamera (see the first screen below)
I added two colliders to the game object (the circle collider is for detecting collisions, the box collider is triggered and used for click detection through IPointer) (see the second screen below)
I implemented the interfaces: IPointerClickHandler,
IPointerEnterHandler, IPointerDownHandler in the game object script. (see the code below)
I have EventSystem object in scene (see the third and fourth screen below)
I checked with a simple project that this combination works
But still in my project any click event isn't detecting at all. I have not idea why. I think the raycast itself doesn't work, because when I look at EventSystem logs in inspector I see that the player object doesn't detected.
UPDATE: I saw that if I switch off the canvas the IPointer gets work. But canvas elements is placed only around the player gameObject (menu buttton), but the game object isn't hided by the canvas
UPDATE 2: Ok, I figured out that even if the canvas panel is transparent it still hides the game objects. So my question is, how can I detect click on game object if the canvas pannel is in front of the game object?
This is the script of the game object:
public class Player : MovingCharacter, IPointerClickHandler, IPointerEnterHandler, IPointerDownHandler
{
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Down");
}
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Clicked");
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("Entered");
}
//other code......
}
This is the MainCamera:
This is my Game Object (Player):
This is the EventSystem:
And this is the project structure:

Use layers!
If you want to be able to hit the object then put your menu on a special layer like e.g. UI and make sure the PhysicsRaycaster2D ignores that layer.
UI will be Interactable anyway since the Canvas's own raycaster already takes care of UI elements.
In general I would also make sure to only mark these elements as Raycast Target that are actually Interactable (e.g. buttons). This way an invisible background panel wouldn't block the input either.

Related

How to check if object is clicked? (unity 2d)

I used method below to check if button(object) is clicked. The problem is that I have a Confiner which is streched over the entire level and as a result method determine this Confiner but not the object that I need. So the question is can I somehow ignore confiner and only check if I clicked an object?
void OnMouseDown()
{
....
}
Implement IPointerClickHandler interface (from UnityEngine.EventSystems). This also works for 3d objects if your camera has PhysicsRaycaster component

Unity: Drag & Drop script doesn't work on my prefab gameobject but DOES work on regular UI gameobjects

I have a simple script that works just fine on any normal UI objects like an image.
But it doesn't work at all for my prefab gameobject, why is that?
I have attached a whole bunch of components to try out, like images, canvas renderer and all kinds, nothing works for me. I can also only SEE the damn prefab when I run the game, I can't see it on the Game tab. I have no clue. This is so strange.
Anyways, If I didn't make myself clear, please let me know what I need to explain or include for anyone to give me an answer?
public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("onBegindrag");
}
public void OnDrag(PointerEventData eventData)
{
this.transform.position = eventData.position;
Debug.Log("ondrag");
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("onEndDrag");
}
}
Does this script only work on UI things? If so, Can I add a component to my prefab so that it is a UI item? Im working in 2d.
By default these primerily UI events are only casted onto UI elements (Image, Text, etc) which have Raycast Target enabled (using the GraphicsRaycaster component attached to the according Canvas).
If you want to be able to also use them on "normal" 3D objects you need
An EventSystem in your scene (already the case otherwise it wouldn't work for UI either)
Collider components on your objects
A PhysicsRaycaster component on your Camera!
For some reason I don't know this is only mentioned in the IPointerClickHandler (Unity 2019.1 and older) but afaik this still applies to all the EventSystem-related events / interfaces.

Unity AR How can i trigger a button in the scene?

I have this little AR-Unityapp for Android and i try to play a video with a button. But the button should not be on the screen ( canvas ) it should be in the scene ( understandable? ). So i made a 3d plane which simply starts the video with a pointer down event but it won´t work. I know that its possible to make this but i have no idea how some help would be helpful ( xP ).
use a world canvas:
Create a canvas and set its "render mode" to "world".
In that canvas you can put your button, give it a 3D location as you would with your plane, but you can use normal UI functionalities, such as buttons, instead of implementing click detections your self.
If you want to trigger a Pointer Down event just follow the steps below
STEPS
Add Physics Raycaster to your Camera as shown below
Add EventSystem object in your scene
Right click in Hirarchy Window -> UI -> Event System
Attack Event Trigger component to the required plane
Select Plane -> Add Component -> Event Trigger -> Add Event of Pointer Down
Now Call the Required method via PointerDown Event (In My case Plane.OnSelected())
ALTERNATIVE OF EVENT TRIGGER
Steps 1 to 2 as above
Attach the below Script to that Plane as below
using UnityEngine;
using UnityEngine.EventSystems;
public class Plane : MonoBehaviour,IPointerDownHandler {
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("CALLED");
}
}
This Method will be called on Pointer Down on the required plane.
As Seen in the above code we are using IPointerDownHandler interface of UnityEngine.EventSystems
I am sure this will clear your problem.

Collisions between UI elements in Unity

I am able to detect collision between UI components and a gameobject if my canvas is rendered in the world space. Here, I am trying to find collision between two UI elements (say UI buttons) when the canvas render mode is screen space overlay.
I added box collider components to my UI buttons and tried using OnCollisionEnter2D and OnTriggerEnter2D. But, the collision is not detected. Is there a way to detect the collision?
The question does not require a code body. However, I have figured out a solution. TO both the UI elements, you need to:
Attach a rigidbody2d component
Attach a box collider component
disable gravity
enable the isTrigger checkbox.
Now in the script attached to one of the UI elements:
void OnTriggerEnter2D(Collider2D other)
{
Debug.Log ("Triggered");
}
This would detect the collision.

Unity3d with vuforia showing 2d image when targed is detected

I have a question about the way how to show simple 2d image on top of detected marker. I have followed some tutorial to show 3d model and it works fine. there is no problem with 3d.
The problem starts when I want to add normal 2d object->sprite . When I add simple sprite I can't add texture and when I insert UI image it's added together with canvas and it is not showed when target is
detected. The original image on editor is placed then so far that it's difficult to find it.
I would be grateful if somebody can highlight me the right direction.
I need to make this image touch sensitive like a button. Clicking into it must show new scene ( I have it but under GUI.Button). The best way is to replace original marker but I can also make new sprite bigger to hide marker under it.
To help understand the answer, here's a quick rundown on how Vuforia handles marker detection. If you take a look at the DefaultTrackableEventHandler script that's attached to the ImageTarget prefab, you'll see that there are events that fire when the when the tracking system finds or loses an Image.
These are OnTrackingFound (line 67) & OnTrackingLost (line 88) in DefaultTrackableEventHandler.cs
If you want to show a Sprite when tracking, all you need to do is put the Image Target prefab (or any other) and make the Sprite a child of the prefab. The enabling and disabling should happen automatically.
However, in case you want to do something more, here's some edited code.
DefaultTrackableEventHandler.cs
//Assign this in the inspector. This is the GameObject that
//has a SpriteRenderer and Collider2D component attached to it
public GameObject spriteGameObject ;
Add the below lines to OnTrackingFound
//Enable both the Sprite Renderer, and the Collider for the sprite
//upon Tracking Found. Note that you can change the type of
//collider to be more specific (such as BoxCollider2D)
spriteGameObject.GetComponent<SpriteRenderer>().enabled = true;
spriteGameObject.GetComponent<Collider2D>().enabled = true;
//EDIT 1
//Have the sprite inherit the position and rotation of the Image
spriteGameObject.transform.position = transform.position;
spriteGameObject.transform.rotation = transform.rotation;
And the below to OnTrackingLost
//Disable both the Sprite Renderer, and the Collider for the sprite
//upon Tracking Lost.
spriteGameObject.GetComponent<SpriteRenderer>().enabled = false;
spriteGameObject.GetComponent<Collider2D>().enabled = false;
Next, your question about detecting clicks on this Sprite. Unity's Monobehaviour fires events for a lot of mouse events, such as OnMouseUp, OnMouseDown etc.
Link to Monobehaviour on Unity's API docs
What you will need is an event called OnMouseUpAsButton
Create a new script called HandleClicks.cs and add the below code to it. Attach this script as a component to the spriteGameObject that you assigned for the above.
public class HandleClicks : MonoBehaviour {
//Event fired when a collider receives a mouse down
//and mouse up event, like the interaction with a button
void OnMouseUpAsButton () {
//Do whatever you want to
Application.LoadLevel("myOtherLevel");
}
}