I'd like to have buttons that are not rectangular. Circle, hexagon, odd shapes... is this possible? I'd heard rumors that this can work with masking, but I haven't observed this to be true.
Answer by Elringus
Nov 07, 2015 at 03:26 PM
Have a look to this asset: https://www.assetstore.unity3d.com/en/#!/content/28601
It checks texture transparency, before deciding whether to send input events for targeted object, which allows a precise interaction with objects that have a non-rect shapes (like circles, triangles, map regions, etc). That way you will be able to make buttons and other interactable UI objects of any shape and they will correctly react to user input.
this thing is called Alpha Raycaster
it is completely supported and updated every few weeks. it's simply a must have until Unity build-in this functionality.
You don't need to purchase an asset from the store to accomplish this. It's quite easy (in Unity 5.5). You use alphaHitTestMinimumThreshold so Unity ignores the alpha pixels of your image as "hit" zones. I use a small simple script I attach to button components.
First, create a C# script:
using UnityEngine.UI; // Required when Using UI elements.
public class AlphaButton : MonoBehaviour
public float AlphaThreshold = 0.1f;
this.GetComponent<Image>().alphaHitTestMinimumThreshold = AlphaThreshold;
Attach this new script to the button component you wish to have a custom hit zone.
Then, you will need to edit your image import settings (your button image) and under Advanced, make sure Read/Write Enabled is checked.
Now, go back to your button component, and in the AlphaButton component in the inspector you can adjust the alpha threshold for your image -- currently set to 0.1f. This value defines the minimum alpha level of a pixel in your button that qualifies as a "hit zone".
It takes about 60 seconds to apply! Piece of cake, and cheaper than a $30 asset!
Answer by robertes
Jan 25 at 09:14 PM
https://docs.unity3d.com/ScriptReference/UI.Image-alphaHitTestMinimumThreshold.html looks promising. Has anyone experimented with it?
Interesting link but be careful. Having multiple images with Read/Write enabled will slow down the execution of your game.
Yes, it works! But you have to make image readable.
Joystick.GetComponent<Image>().alphaHitTestMinimumThreshold = 0.01f;
Answer by Screenhog
Mar 27, 2015 at 05:42 PM
I finally found a way to make it work for certain shapes, without resorting to custom code.
Create a button.
Create an image. Make it a child of the button.
Offset the image so that at least part of the image is not within the quad area of the button.
Press Play, and mouse over the child image. It should be a clickable surface for the button.
Now, if you create a transparent image, and use that as a child of a button, you can make a new, hidden clickable area of the button. With a little creativity, you can use three overlapping rectangular images to designate a hexagonal button area.
Obviously, this technique won't work well for certain shapes (e.g. circles, any shape with an angle less than 90 degrees). However, it certainly helps me, as I was wanting a hexagonal button.
Amazing point: I guess it uses "area of any child". Wild stuff!
Note thought that (5.3) it still just uses the overall rectangle of the image - it does not know about or understand transparency.
Answer by RudyTheDev
Dec 14, 2014 at 04:19 PM
You can script custom areas/shapes for event interaction via ICanvasRaycastFilter.IsRaycastLocationValid. Here's a similar forum post I used for reference. Here's an implementation script I use to have an optional BoxCollider2D "mask":
public class RaycastFilter : MonoBehaviour, ICanvasRaycastFilter
private RectTransform rectTransform;
private new BoxCollider2D collider2D;
public void Awake()
rectTransform = GetComponent<RectTransform>();
collider2D = GetComponent<BoxCollider2D>();
public bool IsRaycastLocationValid(Vector2 screenPosition, Camera raycastEventCamera) //uGUI callback
// If we don't have a collider to check against, any raycast can be captured
if (collider2D == null)
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPosition, raycastEventCamera, out localPoint);
Vector2 pivot = rectTransform.pivot - new Vector2(0.5f, 0.5f);
Vector2 pivotScaled = Vector2.Scale(rectTransform.rect.size, pivot);
Vector2 realPoint = localPoint + pivotScaled;
Rect colliderRect = new Rect(
collider2D.center.x - collider2D.size.x / 2,
collider2D.center.y - collider2D.size.y / 2,
collider2D.size.y); // TODO: CACHE
bool containsRect = colliderRect.Contains(realPoint);
I would imagine you can extend this to whatever needs, including actual sprite's pixels (though sliced and such would need fancier UV maths). Here's another forum post using Mask.
Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.
The best place to ask and answer questions about development with Unity.
To help users navigate the site we have posted a site navigation guide.
If you are a new user to Unity Answers, check out our FAQ for more information.
Make sure to check out our Knowledge Base for commonly asked Unity questions.
If you are a moderator, see our Moderator Guidelines page.
We are making improvements to UA, see the list of changes.
Answers and Comments
34 People are following this question.
New Gui 4.6 - How to use new GUI for inventory system
Change current selected component for Event System uGUI
Unity RenderTexture with RawImage is black (iOS)
How to rotate webcamtexture?