Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Larger button colliders for touchscreens?

Discussion in 'UGUI & TextMesh Pro' started by bluescrn, Dec 5, 2014.

  1. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    Hi,

    When working with NGUI in the past, I'd often make button colliders significantly bigger than the actual button graphic, as this helps make them more responsive on phones with small screens.

    With uGUI, separate collider components aren't used - which is good in some ways - but it leaves no obvious option for tweaking the hitboxes independently of the graphics.

    Are there any nice solutions for this that I might have missed? (Putting a large transparent border around the buttons isn't ideal - as in some place, the colliders can't be expanded in a particular direction, for example if a group of buttons are close together)
     
  2. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    332
    Check out the FAQ on this forum. I saw some stuff about non rectangular click area there, and i believe this could also address the 'larger rectangle click area' requirement as well. It would imply creating an additional component for that, where you'd specify the size of the clickable area, but i guess you'd end up with something fairly similar to the way it works in NGUI
     
  3. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    332
    'Add a component that implements ICanvasRaycastFilter. In your implementation of IsRaycastLocationValid, reject all points that are 'outside' your custom hitbox shape. It's up to you how you want to do that, but for example for a circular hitbox you could measure the distance between the point and your object's center and reject the point if that distance is greater than your circle's radius.'

    That' what i was referring to. Hope this helps
     
  4. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    I finally got around to giving this a try - but it doesn't look like it works to make hitboxes *larger* than the RectTransform.

    In my initial tests, I'm finding that IsRaycastLocationValid is only being called if the cursor is within the bounds of rect transform :(

    Are there any other options to consider here (other than making button images with a big transparent border - which isn't really viable, as in some places there's only space to extend this hitbox in certain directions )?

    This must be a fairly common requirement for mobile games - you can make things feel far more responsive by using oversized hitboxes?
     
  5. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    I suppose one option mightd be to create a subclass of Graphic that serves purely as a hitbox, then add a this on a separate GameObject with a larger RectTransform to each button?

    But that seems very inefficient, I don't want to create a whole load of unnecessary drawing/batching cost.
     
  6. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    This was one of the first things I chewed my lip over when I switched to Unity UI. It's easy to work around with a seperate button collider, but an immense pain in the backside when you have a complex UI subject to lots of changes.

    It was established long before iPhones that buttons need margins.

    Btw, the script linked to in the FAQ leads to a 404.
     
  7. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
    Add transparent image with stretch, stretch anchors and borders like -10, -10, -10, -10 as a child of a button.
     
  8. bluescrn

    bluescrn

    Joined:
    Feb 25, 2013
    Posts:
    628
    Yeah, it'd work, but it's an ugly hack, and won't help with performance on mobile...
     
  9. 3agle

    3agle

    Joined:
    Jul 9, 2012
    Posts:
    508
    It would be good to hear from Unity on this issue, I don't like the idea of extra components when it should be relatively easy to resize a hit area of a button. Is this something Unity are looking to expose in the future, or are we going to have to make workarounds?

    For instance, a button in our project:



    This is an Image with Button component, and a separate Text component under a horizontal layout group.
    Currently, there is no way to allow the user to click the text to also click the button. (Without making the text also a button, or a separate invisible Graphic, both of which have their own problems).

    @Tim C ? (Sorry, don't mean to single you out, but you respond on the UI threads a lot :) )
     

    Attached Files:

    Last edited: Feb 9, 2015
  10. Agent_007

    Agent_007

    Joined:
    Dec 18, 2011
    Posts:
    899
    bluescrn and 3agle like this.
  11. Agent_007

    Agent_007

    Joined:
    Dec 18, 2011
    Posts:
    899
    I did some work for this.
    https://bitbucket.org/Agent_007/unityuiwithcolliders/

    If one builds UI from that repo then she/he can choose GraphicCollider option for all UI elements that based on Graphic class. But you have to enable debug option from Unity before this selection shows up.

    There are four options for GraphicCollider:
    Rectangle <-- same as the current implementation of UI
    Collider <-- Use 3D collider
    Collider2d <-- Use 2D collider
    None <-- Ignore all raycasts, remember to add this to child elements also

    As you might have guessed this implementation isn't really industry ready solution, but it should somewhat work. I have included as small test scene for this.
     

    Attached Files:

  12. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    I don't understand the need here. One way or another, if you want a bigger collider than image, you need the image and collider on separate gameobjects, and it's quite possible to set it up using just what's already available.

    e.g. if you want an invisible clickable margin between your button's collider rect and the image:

    1. create an image child of the button
    2. copy the button's image component values to the child's image component
    3. delete the button's image component
    4. drag the child from the hierarchy into the "Target Graphic" field of the button parent's transition
    5. add Horizontal Layout Group to the button and set your padding values however you want them

    You can either delete the text if you don't need it, or let the HLG align it next to the button (what 3agle wanted, I think), or drag it inside the image and have it behave just like a normal button does.

    To me it feels really flexible how it is. I'd be interested to know what you can do with custom colliders that you can't do this way.
     
    3agle likes this.
  13. Pix10

    Pix10

    Joined:
    Jul 21, 2012
    Posts:
    850
    Flexible isn't the same as practical. The point of a visual UI system is to make creating user interfaces a pleasure, or at least not a pain in the backside, which is what workarounds become when you have multi-step processes and have to create possibly hundreds of buttons and variations over the life of a project. That's time that should be spent elsewhere.
     
  14. 3agle

    3agle

    Joined:
    Jul 9, 2012
    Posts:
    508
    This is exactly what I wanted, and I now feel very stupid for having not figured it out!
    Thank you!

    I do think that for mobile uses, customisable hit areas would be a nice addition.
    Supposedly you could do it with the padding on a layout group in a similar way gfoot suggests, though that seems a bit hacky and likely not great for performance (If only for the fact that you add an additional gameobject).
     
  15. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    Sure, I don't mean to say this kind of support shouldn't be added, just that the behaviour can technically be achieved with the existing primitives, and without introducing any performance problems.

    You could certainly make a custom script to create these buttons the way you want them - you don't have to do all these steps by hand each time.
     
  16. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    Actually I was wrong about this - the reason my buttons were working with a larger hit area was that the text element inside the button was larger than the button itself, as by default it fills its parent button. This is OK in some cases, but not others, as the text won't wrap within the button graphic, it will fill the entire clickable area.

    So I see now the need for a non-rendering collider, which participates in hit-testing but does not incur any rendering overhead. It could then be applied to the button object, and then its entire bounding rectangle would be clickable, even areas that aren't actually covered by renderable children.

    3agle's case should still be fine though.