Search code examples
c#buttonunity-game-enginescale

How to scale down button hitbox


In my project I have a button, this button is of a certain size and has children. My problem is that the hitbox of said button is much too big and you can click on it from outside of the Image that it displays.

For this, I would like to keep all the animations and events which come with a button but I would like to shrink its hitbox. Either shrinking it by only allowing an OnClick event to be called when on a non transparent part of the image or by shrinking the rectangular hit Is this possible? I've searched online and found nowhere that spoke of shrinking it, only of enlarging it.

Here is what my button looks like:

  • MyButton : Image, Button, Animator

    • Title : Text

    • Multiplier : Text

    • Glow : Image, Animation

When I press on the button, I change the Image of MyButton and enable the Image of Glow which with it's animation, makes it appear to glow.

Is there any way of shrinking the hitbox of a button?

Thank you.


Solution

  • You can do this by adding this script to said button and then adding some sort of a 2D collider to it. I use this for some buttons with irregular shape.You can use any collider that fits your button. Note there is also a way to make the click ignore the transparent part but I prefer this one.

    using UnityEngine;
    using UnityEngine.UI;
    
    [RequireComponent(typeof(RectTransform), typeof(Collider2D))]
    public class Collider2DRaycastFilter : MonoBehaviour, ICanvasRaycastFilter
    {
        Collider2D myCollider;
        RectTransform rectTransform;
    
        void Awake()
        {
            myCollider = GetComponent<Collider2D>();
            rectTransform = GetComponent<RectTransform>();
        }
    
        #region ICanvasRaycastFilter implementation
        public bool IsRaycastLocationValid(Vector2 screenPos, Camera eventCamera)
        {
            var worldPoint = Vector3.zero;
            var isInside = RectTransformUtility.ScreenPointToWorldPointInRectangle(
                rectTransform,
                screenPos,
                eventCamera,
                out worldPoint
            );
            if (isInside)
                isInside = myCollider.OverlapPoint(worldPoint);
            return isInside;
        }
        #endregion
    }