Search Unity

OnPointerClick not firing, what am i missing?

Discussion in 'Scripting' started by TheCelt, May 3, 2017.

  1. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    Hello

    My Game Object has all the necessary components for it, Event System and Standalone Input Module.

    I have inherited the correct classes and it's methods required. But it still won't trigger.

    I have:


    Code (CSharp):
    1. public void OnPointerClick(PointerEventData eventData)
    2. {
    3.         Debug.Log("Test");
    4. }

    I have no errors, it compiles fine but i am not receiving the message "test" on mouse down. What else do i need to get this working?
     
    Filip8429 and Necronomicron like this.
  2. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Does it look like this in full?
    Code (CSharp):
    1. using UnityEngine.EventSystems;
    2.  
    3. public class ClassName: MonoBehaviour, IPointerClickHandler
    4. {
    5.     public void OnPointerClick(PointerEventData ped){
    6.          //whatever happens on click
    7.     }
    8. }
    But i personally had no success with the click event even with all of the above perfect and working. I would rather use the pointerUp and/or pointerDown events instead. For one they work, and you have more control over the click with what happens on down and on up.
     
    Necronomicron likes this.
  3. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    Yes it has all that, i have tried the up and down methods too but they don't fire also. All i want to do it click and get the position in the environment. Yet it just won't trigger the methods.

    When i add a collider to my camera, it works - but thats not what i want, i want to hit the box collider on a different game object, basically my floor game object.
     
  4. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    andrenospam0 likes this.
  5. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    I thought OnPointerClick also works for world stuff too using the physics ray caster instead of the graphics ray caster? The documentation doesn't mention it being UI specific?
     
    C0DEP1GLET likes this.
  6. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    If you want the event system to take care about 2D/3D objects, you'll need the PhysicsRaycaster or Phyics2DRaycaster on your camera.
    For the event listeners, either use the interfaces that you've already attempted to use or EventTriggers.
     
  7. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    I have the physics ray caster, i am trying to click the floor in my environment but it's not triggering the method.
     
  8. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
  9. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Is there any collider attached to your floor?
     
  10. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    Yes a box collider which covers the entire floor layout - its much bigger than the camera view. So i'm definitely clicking within the box collider's size. http://i.imgur.com/BZTn0t3.png
     
  11. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    Also this:



    Seems to suggest it is detecting my box collider too... yet not firing the method when i click??
     
  12. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    There must be something wrong in your setup. Try it with a newly created scene.

    Add a cube and attach your script.
    Create the EventSystem with the StandaloneInputModule.
    Add the PhysicsRaycaster to your camera and try again.

    That's all it takes.
     
  13. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    Well this is my current setup:

    Code (csharp):
    1. GameObject: GameManager ¬
    2.                  Event System
    3.                  Standalone Input Module
    4.                  ClickClass (My own script which has the method posted in original post)
    5.  
    6. GameObject: Camera¬
    7.                  Physics Raycaster
    8.  
    9. GameObject: Floor¬
    10.                  Box Collider
    Is that a correct setup or wrong?
     
  14. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    I'll assume OnPointerClick/Down/Up can work for non-UI objects, but I will stick with my previous statement that OnPointerClick simply does not work from my own personal experience using it. Use OnPointerDown and/or OnPointerUp instead.
     
  15. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    742
    I have all the methods implemented:


    Code (CSharp):
    1. public class MouseSystem : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler {
    2.  
    3.     public void OnPointerClick(PointerEventData eventData)
    4.     {
    5.         Debug.Log("Test1");
    6.      }
    7.     public void OnPointerDown(PointerEventData eventData)
    8.     {
    9.         Debug.Log("Test2");
    10.     }
    11.     public void OnPointerUp(PointerEventData eventData)
    12.     {
    13.         Debug.Log("Test3");
    14.     }
    15. }
    I seem to get no logs unless the script is attached to the object itself, rather than a global object and detects what i hit first.
     
    mrsekman44 likes this.
  16. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    When used in UI, the script with the pointer click/down/up methods needs it to be on the object as well, same with how a button detects clicks on itself and nothing else. onmousedown works the same way as well.

    if you wanted a general thing, it would have required a physics raycast detecting the first object was hit by the ray, or using the PointEventData to check objects in the ray's path, but that required sieving through the entire stack of objects, which requires knowing what you want prior to clicking.
     
    MrPapayaMan likes this.
  17. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    You need to have the PointerDownHandler on the object you're trying to click on, like Laparen suggests. You can also put it on any of its ancestors, at least if it works like the canvas ui and trickles up the hierarchy, but you can't put it on the camera.
     
    rmele09 and Kiwasi like this.
  18. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    this, your click class is on the wrong object. it needs to be on the floor with the collider
     
    rmele09 and Kiwasi like this.
  19. douglassophies

    douglassophies

    Joined:
    Jun 17, 2012
    Posts:
    141
    Maybe i should start a new thread but its mentioned here so...
    I think a better method for some scenarios would be to have a mouse class that detects what the mouse is doing, hovering, pointing, etc., and then calls the objects under it as necessary.
    • Example 1, i hover over a UI or 3d object for long enough and it calls a label script that populates with the name of the object its over like a little tooltip.
    • Example 2: It is clicked and checks what is beneath it. Its a 3d object so it goes to a switch statement for them. Its a type of character so it does a get component<ISelectable> and calls select on it. The character itself will know that its either an enemy so select() should give details or its of type payerControlled so it should give command options.
    Do people agree this is a good pattern? If not can you link or briefly describe how you would do it?
    If so would i just run a graphics and physics raycast every frame or is there a nicer way to do it?
     
  20. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    The basic idea is good, and there are already different versions of input systems that are split up into modules and do this in a more advanced fashion. One of those does already come with Unity itself but does not allow as many features as others out there.
    One of the most advanced open-source systems I've come across so far has been written for for the Microsoft's Hololens.

    The general idea is that you'd write a submodule for all desired input sources. The module forwards it's specific input to a manager, which in turn dispatches the equivalents of input behaviour as a certain type of event, providing more information through event args to distinguish between the actual source of the event, just in case you need that (hand gesture, touch gesture, mouse input, keyboard, controller, speech recognition, ...).

    You'd only need to subscribe to that manager for PointerClick events for example. If you need to distinguish between the different potential sources you're able to do that.
    Or you'd subscribe to a particular submodule, that's also fine.

    Example: The manager raises an "PointerClick" event, e.g. when mouse is clicked, hand gesture for click (HoloLens: AirTap), or when a key has been clicked which has been configured to represent a "selection", a single-tap for a touchscreen-device and so on and so forth.

    You could even hook up all kinds of weird input sources that feed their particular input to the manager, which then dispatches it as certain event types.
     
  21. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    @Laperen : It's weird you can't get that to work. I find that interface very useful. :)
     
  22. douglassophies

    douglassophies

    Joined:
    Jun 17, 2012
    Posts:
    141
    Thanks for the reply. I Googled for a few solution but not sure what you would call it so not much luck. Got results about Unitys new input manager but that is not really the same thing i am after as far as i understand. I checked out the hololens project but it was a bit complicated and i decided not to waste much more time on it. So for now i have gone with firing a graphics and physics ray cast every frame and handling the results myself.
     
  23. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    There is nothing wrong about it. :) As I said, your idea is basically the same, with the only difference that you've currently limited it to the mouse so it might end up being a little more specific.
    You can always extend that and you're right, sometimes you just don't need such complexity - it's often rather SDK/Framework development that tries to cover a large variety of potential use cases.

    Anyway, just to encourage you to follow your idea: The more complex input systems just do it pretty much the same way, there's a single entity somewhere burried in the system that fires one raycast every frame, which then updates all kind of stuff such as things like 'pointer entered on gameobject XYZ, pointer exited ... , hovering over GameObject' and throws the corresponding events.

    As complex as it may sound, it's actually quite nice.
    Often you find many scripts in a project that do all fire their own raycast, extract the object that was hit and so on and so forth - even if the input information is always the same, such as center of screen, no specific layer ... In large projects that can cause quite some significant overhead.

    From what I've understood you want to avoid that redundancy, and that's a good thing.
    Keep it up!
     
    Last edited: Sep 3, 2017
    douglassophies likes this.
  24. douglassophies

    douglassophies

    Joined:
    Jun 17, 2012
    Posts:
    141
    You are very helpful. Great to get some reassurance i am not doing something bad or reinventing the wheel too much!
     
    Last edited: Sep 3, 2017
  25. eltrexx

    eltrexx

    Joined:
    Feb 1, 2018
    Posts:
    11
    I don't understand.
    I have a simple (test) 2D scene.
    I have 2 UI panel in it (auto creating canvas and eventSystem).
    In one of the Panels, I create an Empty GameObject.
    On this empty gameObject I add a UI Button as a child object.
    Then I add a Physic Raycaster 2D on the main camera
    Then I add a 2D box collider on the empty gameObject (well not empty anymore)
    I then move the handle of the 2D box collider to fullfill the GameObject
    Then i create this C# script :
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class SimpleLiteEventHandler : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler
    7. {  
    8.  
    9.     public void OnPointerClick(PointerEventData eventData)
    10.     {
    11.         Debug.Log("LITE OnPointerClick");
    12.     }
    13.  
    14.     public void OnPointerDown(PointerEventData eventData)
    15.     {
    16.         Debug.Log("LITE OnPointerDown");
    17.     }
    18.  
    19.     public void OnPointerUp(PointerEventData eventData)
    20.     {
    21.         Debug.Log("LITE OnPointerUp");
    22.     }
    23. }
    I add this script to the "empty" GameObject.

    I hit play and nothing happen when i click on space around the Button (corresponding to the area of the 2d box collider) or on the button itself !

    It only work when i remove the script from "empty" gameobject and attach it to the child UI button istead !

    But I want the script to work on the "empty" gameobject level !
     
  26. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I realize that you are new here, but in the future if you have a question, please post a thread of your own and describe the problem/question, as you did well, mind you :)

    Your issue is that there is no raycast target, I believe. If you add an image it will work. You can set the image's alpha to zero to mimic it not being there. :)
     
  27. eltrexx

    eltrexx

    Joined:
    Feb 1, 2018
    Posts:
    11
    Thanks for the answer.

    ... I though it would be more logic not to create a new thread of the same question ...

    Adding a transparent image does the trick, but then I don't even need a collider ! So i suppose theses are for the game object in scene out of UI canvas ?

    The new issue is that it work on the space around the UI button but not on the button itself as it take over priority to handle clicks.

    But I want both :
    When I clicks on the button I want
    The normal behavior of the button clicked to fire (for now only a tint change as default)
    + My script behavior (Debug.Log())
     
  28. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Hmm, that's odd, because I tried a setup like so:
    panel
    child empty / image
    child of empty/ image : button

    and I can interact with the button without any issue.

    And yes, generally speaking I would say the 2d raycaster is for sprites with a collider, 3d for other game objects with colliders, and just the graphics raycaster for UI elements, with a raycast target component.
     
  29. eltrexx

    eltrexx

    Joined:
    Feb 1, 2018
    Posts:
    11
    Yes you can interact with the button like me, but it doesn't log anymore "Debug.Log("LITE OnPointerClick");" and the 2 other

    This is because the button has also an Image component with a Raycast target in it. So either I let this checked and i can interact with the button but don't have the log anymore on console, or I uncheck it and I have the log on console but can't interact with the button anymore.

    If I want both I don't know how to (easily) do it.
     
  30. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ah okay, I misunderstood a bit..so why not just put the script on both game objects?
     
  31. Ashokan

    Ashokan

    Joined:
    May 7, 2011
    Posts:
    2
    You need an EventSystem in your Hierarchy, otherwise the events won't be triggered.
     
    FionNoir, Nelsonmsg and path14 like this.
  32. losingisfun

    losingisfun

    Joined:
    May 26, 2016
    Posts:
    36
    I've had the same problem, however for a canvas UI object, all I did was add a button component to the object and suddenly the OnPointerClick works. This was very elusive because both OnPointerEnter and OnPointerExit were working, but not the Click.
     
  33. Coopasetic

    Coopasetic

    Joined:
    May 3, 2013
    Posts:
    1
    I had this issue and I was missing the interface extension in the class declaration like this

    Code (CSharp):
    1. public class ItemHandler : MonoBehaviour, IPointerDownHandler
    2. {
    I know this thread is old, but hopefully this helps someone!
     
  34. BjoUnity3d

    BjoUnity3d

    Joined:
    Jul 24, 2012
    Posts:
    60
    Just in case someone lands here with my issue, I had created an image with Event Trigger / PointerDown and it was driving me nuts that it wouldn't work. Turns out the Image was not on layer UI. It was on layer Default. UPDATE: Actually no lol it was the Override Sorting checkbox that got left on and set to 0 on the Canvas in DoozyUI. For some reason visually my button was showing up but was unclickable. Turning off Override Sorting fixed it. UPDATE2: Landed here again because I had a Canvas Group on the object with block raycast unchecked.
     
    Last edited: Sep 26, 2020
  35. LeopardX

    LeopardX

    Joined:
    May 31, 2015
    Posts:
    64
    Thanks guys I was missing the EventSystem in the scene for gameobjects, all works for me too now.
     
    FionNoir likes this.
  36. cntzero

    cntzero

    Joined:
    Aug 13, 2020
    Posts:
    1
    I had a similar problem. In my case, an empty Event Trigger component has been added to the game object I want to click.
    When I removed the Event Trigger component, OnPointerClick started firing in code.
     
  37. alexq4p3

    alexq4p3

    Joined:
    Sep 26, 2020
    Posts:
    3
    Solved!
    There was a transparent Canvas covering the entire screen with "Block Raycast" checkbox active.
    I simply disable it and IpointerClick worked.
     
    tjmaul likes this.
  38. mfatihbarut

    mfatihbarut

    Joined:
    Apr 11, 2018
    Posts:
    1,059
    You are my hero!!! Don't be afraid of answer any question even if it is old.
     
  39. Filip8429

    Filip8429

    Joined:
    Dec 16, 2018
    Posts:
    20
    I have an issue where OnPointerClick is firing from a mouse click but not from a gamepad press. My gamepad input works fine otherwise. Does this funciton not work with gamepads? If so what are the alternatives?
     
  40. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    it depends on how you are accessing your gamepad input. the event system has what are called InputModule components on the EventSystem gameobject. By default they support touch input and standalone (eg keyboard+mouse). on those modules they have a BaseInput class which handles the hardware-level gathering of input data.

    you can extend/override this system at runtime by implementing a class that derives from UnityEngine.EventSystem.BaseInput and setting that class instance to the inputmodule's inputOverride property when you want it to override the default implementation. In that class you can specify if there should be a mouse cursor present and where it should be on that frame based on gamepad input. You can then set inputOverride back to null whenever and the inputmodule will revert to the normal input behavior.
     
  41. idzdigital2

    idzdigital2

    Joined:
    Oct 1, 2020
    Posts:
    1
    if above mention things are not working then try to increase the size of box collider 2d if you see there is warning like "collider did not create any collision...." In box collider2d component.
     
  42. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,598
    I was missing a PhysicsRaycaster on my camera...
     
  43. JavierHC

    JavierHC

    Joined:
    Apr 15, 2017
    Posts:
    1
    I had the same problem, but I fixed it by adding more handlers to my code (even when I don't use those handlers but only having their methods too).

    The not working line:
    public class ClassName: MonoBehaviour, IPointerClickHandler

    How it fixed it:
    public class ClassName: MonoBehaviour, IPointerClickHandler, IPointerUpHandler, IPointerDownHandler

    It looks like using those other handlers makes the camera/project/idk to recognize the clicks.
     
  44. prasetion

    prasetion

    Joined:
    Apr 3, 2014
    Posts:
    28
    I actually had the same problem in my android project, i already added the interface, collider and physics raycaster, but it did not work at the editor. After I build and run into real device, it works. I don't know what happens