What would be the practice for making very strangely shaped buttons

Defold forum user,
I need to make some buttons that are extremely irregular in shape and want advice on the best method to implement these buttons.

My known options are:

  • Make the custom structures I need out of many GUI nodes and just chain them so they correspond to the same thing
  • Use GOs and manually detect if the click is within by using mouse coords
  • Layer hitboxes so they would be rectangular but overlapped by functionless GUIs that intercept clicks going outside of the intended hitbox

I’m open to any and all feedback and would appreciate some insights into the least tedious and fastest at runtime option

Thanks for reading!
Grify

How “extremely irregular” are we talking about? Users don’t expect a “pixel perfect” detection on buttons, I would argue that it is almost the opposite as pixel perfect detection would increase the chance that they “miss” the button (due to it being smaller).
As an example many games that have ellipse type buttons (that uses sprites) detect your click “outside” the ellipse of the button, but because a user tend to click in the center of a button it isn’t noticeable (if users accidentally click on the “outside” of your buttons thus activating it your GUI have bigger problems).

That said, if I really had to have a “hitbox” of a button be something completely different I would either.

Do it with physics and collisions

As seen in @britzl physics based linker/switcher example . Where he have a small collision object follow the mouse/touch position and have collision shapes set up on the game objects to detect when the mouse/touch object collides with it.

Stay in GUI and chain pick node.

If your setup is extremely complex and you want to stay in gui you can chain pick nodes, for (in theory) added performance you can also add groups.
Like this example

--on_input
if gui.pick_node("box_node_that_cover_all_other_nodes") then
  if gui.pick_node("node1") or gui.pick_node("node2")  or gui.pick_node("node3")  ... then
    -- button_pressed
  end
end

That way you do not check all the “sub” nodes at all times but only when over the big node.


But in the end, if you do not plan to have a lot of these kind of buttons I do not think the performance hit will be significant enough for you to over engineer it. Instead as always implement it “the easy way” and if it becomes a performance hog then optimize it, don’t spend days optimizing something that might become a problem.

10 Likes