I am implementing a weapon wheel in Unity and I have most of it all worked out, but am struggling with one issue:

My weapon wheel looks a bit like this one (example only):

enter image description here

And mine is for something else, not weapons.. but that doesn't matter.

There is no mouse involved.. the idea is to spin the wheel left and right until you've selected the item you want.. the selected one would be the one in the top most position (the example above is the bottom most position, it seems).. Anyway, I have it moving left and right just fine.. the problem now is trying to figure out which button (yes, they are implemented as UI buttons) is currently in the selected position.

My initial thoughts are

  1. To calculate the center X, Y pair of the "selected" location and store those..

  2. When user hits action button to select, then iterate through the 8 buttons I have in that weapon wheel and..

  3. Calculate the current X and Y of each button in the loop

  4. If the button overlaps the "selected" location, then invoke that button's click()

This is proving to be a real pain in the neck though.. for example, I have found that the button transform's positon is always 0,0 until you show the UI at least once.. so I have to use Update() instead of Start().. In addition, trying to calculate the overlap means needing to add width of button to current X and height to current Y and getting pixel width does not seem to be an easy task.

Is there some simpler way to do this? How can I have a "selected" button on my weapon wheel without too much fuss like this? And if this really is the only way, then please let me know how I can get the pixel width and height of buttons.

  • 1
    \$\begingroup\$ If your buttons are equally spaced like this, then worrying about pixel positions and widths and heights seems like overkill. Just track the rotation angle of the wheel as a whole, and wrap/round it into one of 8 equally-spaced buckets. That rounded value is now the selected index in your array of buttons. \$\endgroup\$
    – DMGregory
    Jul 16, 2020 at 11:06
  • 1
    \$\begingroup\$ Either the above - or why not map your input directly to a normalised float value for percentage. That way you have the percentage round the wheel, which can be used to drive the rotation of the UMG element and the selection \$\endgroup\$
    – Natalo77
    Jul 16, 2020 at 12:17
  • \$\begingroup\$ Bloody fantastic.. @DMGregory I went with yours. Will post the solution below. I would say you should post the answer and I mark it as the solution, but I remember you're the same guy who helped me before and said you didn't want that. Assuming the same here? \$\endgroup\$
    – Matt
    Jul 16, 2020 at 12:32

1 Answer 1


Okay, I went with @DMGregory's answer (see his comment above).

So I was already tracking the rotation angle of the wheel anyway.. then all I needed to do was normalize the degrees between 0 and 360 and then figure out which button is at which degree... like so:

An extension method for the normalizing of degrees first:

public static int NormalizeCircleDegrees(this int orientation)
    orientation %= 360;

    if (orientation < 0)
        orientation += 360;

    return orientation;

And then this method:

private Button GetSelectedButton()
    int normalizedDegrees = currentRotation.NormalizeCircleDegrees();

    switch (normalizedDegrees)
        case 0: return Buttons[0];
        case 45: return Buttons[1];
        case 90: return Buttons[2];
        case 135: return Buttons[3];
        case 180: return Buttons[4];
        case 225: return Buttons[5];
        case 270: return Buttons[6];
        case 315: return Buttons[7];
        default: return Buttons[0];

Just make sure the buttons are in the right order and voila! Much simpler...

  • \$\begingroup\$ Nice solution! I presume you increment your rotation in discrete 45 degree clicks, so it can never be a little off, like at 91 degrees instead of 90? \$\endgroup\$
    – DMGregory
    Jul 16, 2020 at 12:43
  • \$\begingroup\$ That's right.. always +/- 45 degrees. It seems to be working very well. Thanks for the help \$\endgroup\$
    – Matt
    Jul 16, 2020 at 12:46
  • 1
    \$\begingroup\$ You can use division to get the index directly, without your switch statement: int index = (orientation/45) & 7; return Buttons[index]; \$\endgroup\$
    – DMGregory
    Jul 16, 2020 at 12:49
  • \$\begingroup\$ Ah, that you are right. Thank you yet again. \$\endgroup\$
    – Matt
    Jul 16, 2020 at 12:55
  • 1
    \$\begingroup\$ I'm staring the potential for a beautiful data driven radial menu tool in the face but I just know it's so overkill for what you need. \$\endgroup\$
    – Natalo77
    Jul 16, 2020 at 13:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .