Unity Round(Circle) Buttons

Unity Round(Circle) Buttons

I have been using unity and C# scripting now for the past 2 or 3 weeks. So yeah i am very new to unity and C#. 
I wanted to know if there is a way to make a round(circle) button without using the rect.
The problem I have now, I am using a 2d sprite to make the button appear round, however when you hover or click with in the rect, it still works.
I saw this asset in the asset store called Alpha Raycaster
Check asset out: Alpha Raycaster on Unity Asset Store
I cannot afford to pay for it right now so I was wondering if there is a free alternative to the Alpha Raycaster for now.
Dose anyone know how we can solve this issue? I obviously only want the button to function when the user hovers or clicks within the sprite and NOT on the alpha surrounding the sprite.

Solutions/Answers:

Answer 1:

There is one easy way that only works for round Shapes.
In your Button callback you could test the distance of the mouse from the center of the button against the radius of the button and only trigger the click or hoover effect when it is within the buttons radius.

But since you are new, maybe focus on making some gameplay rather than the button design. While a good look and feel are important, i believe a working game will motivate you more. Try focusing on what you can do, instead of what you can’t.

Answer 2:

YES! THANK YOU @trollingchar.

I added the code to a script and attached the script to the button.
that is exactly the functionality i was looking for.

check out the link to the code:
https://forum.unity.com/threads/none-rectangle-shaped-button.263684/#post-2146709

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(Image))]
public class RaycastMask : MonoBehaviour, ICanvasRaycastFilter
{
    private Sprite _sprite;

    void Start ()
    {
        _sprite = GetComponent<Image>().sprite;
    }

    public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
    {
        var rectTransform = (RectTransform)transform;
        Vector2 local;
        RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform) transform, sp, eventCamera, out local);
        // normalize local coordinates
        var normalized = new Vector2(
            (local.x + rectTransform.pivot.x*rectTransform.rect.width)/rectTransform.rect.width,
            (local.y + rectTransform.pivot.y*rectTransform.rect.height)/rectTransform.rect.width);
        // convert to texture space
        var rect = _sprite.textureRect;
        var x = Mathf.FloorToInt(rect.x + rect.width * normalized.x);
        var y = Mathf.FloorToInt(rect.y + rect.height * normalized.y);
        // destroy component if texture import settings are wrong
        try
        {
            return _sprite.texture.GetPixel(x,y).a > 0;
        }
        catch (UnityException e)
        {
            Debug.LogError("Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'");
            Destroy(this);
            return false;
        }
    }
}

for those that are too lazy to follow the link 🙂
here is the code snippet.

It was posted by @senritsu

if i could hug you right now i would 🙂

Answer 3:

This is much simpler than it seems. Unity has functionality built in for this.

theButton.alphaHitTestMinimumThreshold = 0.5f;

Documentation

What this does is only register hits from the raycast if the pixel hit has an alpha of 0.5 or greater.

References