How i can create circle widget with button in pizza piece shape?
Unfortunately, the best way to handle this right now would be to create a number of different buttons on each “slice” of the widget of varying sizes to fill the space with transparent button images, then set all their click and hover events to execute the same function. UMG currently only supports rectangular button colliders. Arbitrary shapes for colliders are coming, but there is currently no ETA. I believe there is a way to do arbitrary collision shapes in Slate, but I unfortunately don’t know enough about Slate to point you in the right direction, I’m afraid.
I would make a custom widget that does the hit detection manually. The whole circle would be one widget, that drew the segments in a material. Then I would override the mouse functions to determine when I was hovered, convert the mouse into local space and figure out which segment by finding the angle of the direction formed by the center -> local mouse point (you can use Atan2 to get the angle). Then a radius check to see if it’s in the circle. Finally I’d take any slice hover information and update a material parameter in tick so that the material could adjust accordingly.
I have made it a bit differently…
- Get the coordinates of the center of your circle.
- Get angle between Mouse Position and circle center.
- Get length between Mouse position and circle center.
- Tick Check on all slices: (“Slice start angle” > Angle < “Slice end”) AND (Length <= Circle radius) AND (Mouse button is pressed)
- Do something, if true
This way you will get your goal and this will work perfectly…
We need better way for making touch/mouse event layouts. Widgets would be perfect if expanded in this direction.
Is this still the case? I have circular buttons that have highlighted images when hovered and clicked, but since the colliders are rectangle, the buttons looks like they are being hovered on when you are not even hovering over them…
Cant it be a simple approach to have transparency or masking of the image/material determine weather the button is interact-able? This is something I thought would have been implemented a while ago
Yes, that’s still the case.
It’s not something we want to just hack in quickly. The approach of using a texture means keeping it resident in CPU memory, and in GPU memory, fully uncompressed, which is not really desirable. Using a material is also nasty, the only way to use a material means adding a frame delay to all hit testing, something we do in the viewport for pixel perfect collision detection even without collision boxes - it’s not a great solution either, means rendering a lot more information.
On top of this, you’re probably only considering a single mask in play, but that’s not an acceptable limitation. e.g. A circular button with a circular mask, inside a mini-map with a circular mask, needs to properly nest, intersect…etc.
The possible approaches I’m considering are using the stencil buffer to allow compositing multiple masks, but it’s going to be kind of crappy having to ‘pop’ the masks off the stencil buffer, maybe it can be made fast - not sure. This allows nesting masked elements, but still requires keeping textures resident on the CPU uncompressed to allow for CPU hit testing. Another approach is doing polygonal hit testing, users define a polygonal outline for a mesh, we do CPU hit testing using the polygon. For handling the rendering, we could do a bunch of triangle intersections, cut / re-triangulate.
In any event, this feature isn’t scheduled to be implemented any time soon. The current focus is on performance, and will continue to be for some time.
Thanks for the explanation! I guess for now Ill just use a bunch of really small invisible rectangles and duplicate them around to make the shapes I need the best that I can for proper click detections
Also, as long as your circular button doesn’t have other elements inside the hit testing box, you can make a custom Widget that internally does it’s own hit testing for actually detecting the click, or changing the visualization. Just so long as nothing else overlaps the airspace of the true slate hit box, you’re fine. Slate will still hit the bounding box of the widget, but you can just ignore it if it’s outside the radius of your sphere button, or you could if you wanted do your own custom hit testing through another method, you just wouldn’t be able to allow the click to pass through areas you actually control. Bubbling up an unhandled input event moves though the parent hierarchy of widgets.
If you were super careful, you could overlap them, just so long as the smaller circles were always on top, and their slate bounding boxes, never intersected with your true hit-able region you’d be fine.