Best way to implement object focusing for 3D object when using arrow keys / D-pad?

Hi. I am thinking of making a 3D object that has buttons on it. The button layouts can vary and they are of different sizes.

How would you implement focusing / navigation on the 3D buttons? I need to support a gamepad and arrow keys for the button selection.

Would you use raycasting to check which buttons are on the left / right / top / bottom side of the currently focused button? Something else? What?

Basically this is like a complicated layouted menu system but in 3D.

Thanks in advance everybody!

Where does the layout come from? What constraints does it follow? How often does it change? What’s the maximum number of buttons you need to deal with at one time?

Does the player actually navigate in 3 dimensions, or is the layout basically planar and just rendered in 3D? How many axes of input does the player have for this purpose?

With raycasting I’d be concerned that the ray might “miss” the button that you’d intuitively want to go to, and end up hitting something far away (or nothing at all). But that might or might not be a likely problem depending on the constraints of your system.

There might not be any good general solution. Even with only 2 dimensions, Unity’s builtin automatic UI navigation sometimes has issues where you can’t get to certain buttons or the movements are unintuitive, and then you have to replace the automatic navigation with explicit manually-defined directions. With 3 dimensions, getting stuck seems even more likely.

The fallback, of course, is that you can let the player navigate on a simple rectilinear grid (with the possibility that many gridspaces might not contain a button, or a button might span multiple gridspaces). Kind of like using a joystick to control a simulated mouse cursor. This is much less convenient for simple menu layouts, but it works for anything.

I’d just put all the buttons in a list and store an int with the index of the current button selected.
Each time an arrowed is pressed, if the menu is opened I’d cycle trhough the different buttons in a row (down arrow adds to the index and up arrow subtracts to the index). If you want him to cycle (go back to the top once it reaches the bottom) make sure to make a condition so that if (index < 0) {index = buttons.Count-1;} and if (index>=buttons.Count) {index=0;} ).
If you also have other colums of buttons, say a left one and a right one, you’d also cycle trhough them using the left and right arrows. just do 2 lists instead of one (or as many as you need), and when the left and right arrow are pressed, you switch between them, and you cycle between them up and down as mentioned. Just remember that every time you switch the colum you reset the index to 0.
Most definelty don’t raycast for this type of task. If you don’t want you buttons to move with respect to the camera, you can use a billboard component.