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 @britzlphysics 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
--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.