Radial Menu

I am trying to make a Real-time Battle Radial Menu, where the user can click on an enemy, and a Radial Menu appears with possible icons of their known attacks and spells. I cannot get the Radial Menu to stay where it originated, rather it follows the mouse using Event.current.mousepos for x and y. Another thing is how would I use textures that can detect if the mouse is hovering above it, for the player to know what they’re selecting? I know Unity build in GUI buttons work for that, but I don’t want to make individual buttons for many attacks and spells.

Thanks for the help.

We’re going to see some code or maybe an explanation of exactly what you’re doing.

Stash the original opening position in a variable, then draw it based on that position instead of the mouse’s current position.

Like:

if(MouseButton(2)){
This-variable = Event.mouseposition;
DrawTexture(at This-variable, etc…);
}

That itself is inside function OnGUI() { }.

When you click the game object, you store the objects transform as a variable. Then you convert this objects position + any offset you want to apply to screen coordinates to get the proper center position for the radial menu.

You need to think about it… if you store the mouse position, then the camera moves, the mouse position is no longer significant in any way.

You would also need to use sin / cos to determine the radial positions around the object. You could either divide it equally, based on the number of icons to display, or else start at position 0, then work your way around to position 1, then position 2.

Here is an example I wrote up, I hope it helps!

#pragma strict
private var selected:Transform = null;
public var skillMax:int = 5;
function Update () {
	// clear the GUI buttons
	if(Input.GetButtonDown("Fire2")){
		selected = null;
	}
	if(Input.GetButtonDown("Fire1")){
		var hit:RaycastHit;
		if(Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), hit)){
			selected = hit.transform;
		}
	}
	// move camera around a bit
	if(Input.GetAxis("Vertical")){
		transform.position.y+=(Time.deltaTime*Input.GetAxis("Vertical")*10);
	}
	if(Input.GetAxis("Horizontal")){
		transform.position.x-=(Time.deltaTime*Input.GetAxis("Horizontal")*10);
	}
}

// how much to spread the icons apart
public var offset:Vector2 = Vector2(100, 100);
// offset where icon 0 begins (90 is the top)
public var degOffset:float = 90.0;
// width and height of the icons...
public var iconSize:Vector2 = Vector2(48, 32);

function OnGUI(){
	if(null != selected){
		// amount to offset each icon around the center
		var radialTic:float = (360/skillMax)*Mathf.Deg2Rad;
		// used to offset where '0' starts
		var radOffset:float = degOffset*Mathf.Deg2Rad;
		// position of the object
		var objPos:Vector3 = camera.WorldToScreenPoint(selected.collider.bounds.center);
		for(var i = 0; i < skillMax; ++i){
			var rad:float = (i*radialTic)+radOffset;
			var guiX:float = objPos.x+Mathf.Cos(rad)*offset.x;
			var guiY:float = objPos.y+Mathf.Sin(rad)*offset.y;
			// hug the screen
			guiX = Mathf.Clamp(guiX, 0, Screen.width);
			guiY = Mathf.Clamp(guiY, 0, Screen.height);
			if(GUI.Button(Rect(guiX-(iconSize.x*.5), Screen.height-(guiY+(iconSize.y*.5)), iconSize.x, iconSize.y), "Test"+i)){
				Debug.Log("Clicked Button "+i);
			}
		}
	}
}

Change line 40 to this:

var rad:float = -(i*radialTic)+radOffset;

To get it to rotate around clockwise instead of counter clockwise.

1094443–41123–$RadialMenuDemo.unitypackage (5.37 KB)

I got what you mean, Bunzaga, and I had to adapt your script to fit mine. It’s a bit unrefined for now, but it works lol;
Thank!