Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

IPointerEnter/Exit/Click on world space UI

Discussion in 'UGUI & TextMesh Pro' started by DreamingInsanity, Sep 25, 2019.

  1. DreamingInsanity

    DreamingInsanity

    Joined:
    Nov 5, 2017
    Posts:
    101
    I have tried over and over again, using what is in the title - IPointerHandlers - and multiple types of raycasting to be able to create a IPointerClick and an IPointerEnter/Exit.
    I do have a camera set in the event camera area but this hasn't made a difference.
    The IPointers don't do anything at all. However, the raycasting sort of works. I have an image that block the raycasts fine. When I set the graphics raycaster to ignore my image, my UI text doesn't block the raycast.
    Here's some screenshots of my setup:
    Screen Shot 2019-09-25 at 19.49.18.png Screen Shot 2019-09-25 at 19.49.31.png Screen Shot 2019-09-25 at 19.49.41.png
    And here is the raycast script:
    Code (CSharp):
    1. public class HoverEffect : MonoBehaviour
    2. {
    3.     public int shift_amount;
    4.  
    5.     GraphicRaycaster raycaster;
    6.      void Awake()
    7.      {
    8.          // Get both of the components we need to do this
    9.          this.raycaster = GetComponent<GraphicRaycaster>();
    10.      }
    11.      void Update()
    12.      {
    13.          //Check if the left Mouse button is clicked
    14.          if (Input.GetKeyDown(KeyCode.Mouse0))
    15.          {
    16.              //Set up the new Pointer Event
    17.              PointerEventData pointerData = new PointerEventData(EventSystem.current);
    18.              List<RaycastResult> results = new List<RaycastResult>();
    19.              //Raycast using the Graphics Raycaster and mouse click position
    20.              pointerData.position = Input.mousePosition;
    21.              this.raycaster.Raycast(pointerData, results);
    22.              //For every result returned, output the name of the GameObject on the Canvas hit by the Ray
    23.              foreach (RaycastResult result in results)
    24.              {
    25.                  Debug.Log("Hit " + result.gameObject.name);
    26.              }
    27.          }
    28.      } //rctTrans.anchoredPosition = Vector3.Lerp(currentPosition,targetPosition, 3f * Time.smoothDeltaTime);
    29. }
    30.  
    (I would link where I got this code but I can't find the post again)

    How can I get a simple on hover and on click detection on a world space canvas?

    Sorry if this doesn't make a huge amount sense, I'm not thinking straight at the moment.
    Thanks,
    Dream
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You should probably post the IPointerEtc. code that is failing to work.
     
  3. DreamingInsanity

    DreamingInsanity

    Joined:
    Nov 5, 2017
    Posts:
    101
    It's exactly the same as the unity example code:
    Code (CSharp):
    1. public class HoverEffect : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
    2. {
    3.     public void OnPointerClick(PointerEventData pointerEventData)
    4.     {
    5.         //
    6.     }
    7. public void OnPointerEnter(PointerEventData pointerEventData)
    8.     {
    9.         //
    10.     }
    11. public void OnPointerExit(PointerEventData pointerEventData)
    12.     {
    13.         //
    14.     }
    15. }
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    How can you tell that it is "failing to work" if the functions don't actually do anything?
     
  5. DreamingInsanity

    DreamingInsanity

    Joined:
    Nov 5, 2017
    Posts:
    101
    They do, I just didn't include it in this script for simplicity's sake (and the fact that I wrote that script quickly because I no longer am using that one, and was trying out raycasting). All it did previously was print out the name of the game object you hovered over. Nothing appeared in the console when I hovered over the text, so I concluded that it wasn't working.
     
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You'd be amazed at how many "help my code isn't working threads" end up with an answer like "you spelled that wrong" or "you put that curly brace in the wrong place". If you post no code, or if you post the example you were following instead of the actual code you compiled, then it's impossible to catch errors like that.

    If you want me to assume that your code is perfect, the next-most-common explanation for those handlers not working would be that you have some other object blocking the raycasts. If you press Play and then select your EventSystem object, you should see some debugging info at the bottom of the inspector that displays useful stuff like the name of the object Unity believes the mouse is currently pointing at.

    If you want me to focus more on your newer approach with the code in your OP, you'll need to clarify more exactly how it is misbehaving.
     
    evshell18 likes this.
  7. DreamingInsanity

    DreamingInsanity

    Joined:
    Nov 5, 2017
    Posts:
    101
    The raycast script I provided was exactly what I was using (and what I compiled). The IPointer(s) script I provided was almost exactly the same, apart from the Debug.log lines, which I removed and that's my mistake.

    That's what i have been checked multiple times. In my very first post, the first image shows the logo 'crash landing' blocking most of the text. When using the raycast script, the raycast was blocked by the image. After not only disabling raycast target on the logo, but also setting the text to it's own layer (this is all to stop the image blocking the raycast) the text did not block the raycast. I don't see why this could be the case - raycast target is enabled, and there is nothing in front of the text that could be blocking it.

    I'm assuming under the debug info in the inspector, the ones I should be focusing on are the 'pointerEnter' and 'pointerPress' if, these do not show anything when hovering over the text - they always stay blank.
    Screen Shot 2019-09-27 at 21.43.51.png
    I would like to focus on the IPointers because it is a much simpler, much cleaner approach however the raycast method has currently had the best results so I will stick to raycasing.

    Here's how it is misbehaving:
    Taking right back to my first post, I mention this:
    I elaborate on this point in this very post:
    ''In my very first post, the first image show the logo 'crash landing' blocking most of the text. When using the raycast script, the raycast was blocked by the image''.
    I would say that's fairly understandable.
    Then what did I do? I made this image a non raycast target so it no longer blocked the raycasts. After doing this I got no output in the console saying anything had been hit. Like I also mentioned in this post, all the text has raycast target enabled. Screen Shot 2019-09-27 at 22.02.51.png

    The only problem I can think of it being is that the text is located outside of the actual canvas.
    Screen Shot 2019-09-25 at 19.49.18.png
    The red arrow is the outside lines of the canvas. The purple arrow is the border of the image. Because the border of the image is inside the canvas, this could be the reason it was blocking the raycast and the text wasn't. However I moved the text onto a completely separate canvas and made sure it was inside the boundaries and it did nothing, it didn't block any of the raycasts.

    Thanks for the replies,
    Dream
     
  8. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    So the raycast hits your Image (when it is a raycast target), but does not hit your Text under any circumstances, and you want it to hit the Text?

    If the EventSystem also isn't noticing the text when you point at it, that suggests the issue doesn't have anything to do with your code, so by process of elimination it presumably has to do with how your objects are set up. But I'm afraid I don't have any more plausible guesses about what that might be.
     
  9. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    1. Ensure you have a GraphicRaycaster component.
    2. Create a Screen Space - Overlay based canvas.
    3. Add a Button component to anything you want to behave like a button, for example the text elements.
    4. Add a transparent Image or look up invisible graphic raycasters for pure text buttons.
    5. Parent the text elements to the game object with the Button component instead of clicking on the text.
    6. Use IPointerClickHandler implementing UIBehaviour components attached to the same game object the Button components are attached to.
    7. Test. If it works, change to world space.

    Your problem is related to using text objects.

    Don't use raycasting for hover effects.
     
  10. DreamingInsanity

    DreamingInsanity

    Joined:
    Nov 5, 2017
    Posts:
    101
    Correct, that's what it should be doing.

    Do I add this as well as the button component?

    I'm not understanding this - if I have added the button components to the text, which was what number 3 said to do, there's nothing else with a button component to be parented to. I can't parent the text to itself, no?
     
  11. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    Your hierarchy should look like this:
    • Parent Game Object: Button Component, Image Component, UIBehaviour : IPointerClickHandler custom component.
      • Child Game Object: Text Component
     
  12. DreamingInsanity

    DreamingInsanity

    Joined:
    Nov 5, 2017
    Posts:
    101
    I have gotten it to work. Thank you for your help!

    Dream.
     
  13. evshell18

    evshell18

    Joined:
    Sep 28, 2020
    Posts:
    1
    OMG, thank you, thank you, thank you! I've been searching for hours on end as to why my pointer events weren't firing and it turns out I had an empty transparent panel from a previous experiment from a long time ago blocking my mouse. Clicking the EventSystem to show what it is pointing at was a lifesaver!