Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Can someone please help me with a radial menu mouse?

Greetings,

I am trying to create a radial menu like you see in GTA V or Dishonored. With the help of the tutorial and various devForum threads i've manged to create the menu itself. However I can't find anywhere any tips on how to create the mouse for the menu, that would consist of an arrow in the center that rotates and points to the currently selected item in the menu.

It was suggested to me to use InputObject.Delta like so,

UserInputService.InputChanged:connect(function(inputObject)
    if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
        local delta = inputObject.Delta	
		print (delta)

however unless the mouse is locked to the center of the screen delta is always (0,0)

I've tried other things but such as :GetMousePosition() and such but i don't want to clutter the post with my failures. If anyone has any advice I'd be most grateful

Thank you for your time

1 comment

0

How are you locking your mouse's movement?

2 answers

menu = script.Parent.Parent.Frame
seletor = script.Parent
local plr = game.Players.LocalPlayer
local m = plr:GetMouse()
while wait() do
	atn = math.atan2(m.X-(menu.AbsolutePosition.X+menu.Size.X.Offset/2),m.Y-(menu.AbsolutePosition.Y+menu.Size.Y.Offset/2)) --Mouse positon to radians
	deg = 90 --This value I used to correct the arrow position
	offset = 150 --The distance between arrow and menu
	seletor.Rotation = -math.deg(atn) --Convert radians to degrees
	cs = math.cos(atn+math.rad(deg))*-1 --Radians to cosine
	sn = math.sin(atn+math.rad(deg)) -- radians to sine
	script.Parent.Position = UDim2.new(0,(menu.AbsolutePosition.X+menu.Size.X.Offset/2)+(cs*offset),0,(menu.AbsolutePosition.Y+menu.Size.Y.Offset/2)+(sn*offset)) --convert cosine and sine into arrow position
end

Hi, I made this code that converts the mouse position based on the menu position in radians, then I convert the radians into cosine and sine and use them to calculate the arrow position (selector) and also the arrow orientation converting the radian in degrees.

(Sorry for my terrible English)

4 comments

0

tf

0

can you tell me what gui elements you used? how many frames and what size, when i use this script the selector goes to the right side of the screen

0

can you tell me what gui elements you used? how many frames and what size, when i use this script the selector goes to the right side of the screen

0

I used 2 frames, one with the name "selector" (the parent of the script) and the other with the name "Frame" (the frame in the middle) The Frame is 100x100 size and the Selector is 30x30 size For me the code works normally, I tried different screen sizes and frame sizes and everything is fine

I'm not sure how those games handle radial menus, but I'll give you my insight.


input.Delta only changes when the mouse is locked (only using a mouse of course). You can lock it by changing MouseBehavior, check the wiki here.

Getting Delta Without Mouse Being Locked

To find the direction a mouse is traveling, you'd want to track the position of the old mouse and compare it with the new mouse.

local UserInputService = game:GetService('UserInputService')

local previousPos
UserInputService.InputChanged:Connect(function(input, gpe)
	if (input.UserInputType == Enum.UserInputType.MouseMovement) then
		
		--since input.Position is a Vector3, we converted it
		--to a Vector2
		local newPos = Vector2.new(input.Position.X, input.Position.Y)
		
		--this a quick if statement, checking if
		--previousPos has a value
		--which initially it doesn't
		--we just set it to the newPos
		previousPos = previousPos or newPos
		
		--to get the delta, you take to new and subtract the old
		--(or the other way, idk math)
		local direction = newPos - previousPos
		print(direction)
		
		--we then set the old position to the new one
		--that way it can compare the next move
		previousPos = newPos
	end
end)

You can also check the magnitude of the direction, that way you have to move your mouse a lot in order to trigger an area.

Alternatives

The use of a mouse moving a certain direction to trigger UI elements is such a strange design that I don't think this is the solution you were looking for. Therefore, I've decided to add more.

Option 1

If you have a radial menu that appears anywhere on the screen and you want an arrow to point to where the mouse is, you'll want to instead take the radial menu's center which you can refer to by GuiObject.AbsolutePosition. Then you subtract the mouse's current position to get a direction which you can apply to the arrow.

Option 2

You can continue to use input.Delta by making the radial menu pop up and locking the mouse in its current position (more info on the MouseBehavior wiki).

Concluding

You need to use math to figure out which element of your UI is in-use. You can use multiple slope equations (learned in school) to find if the mouse is between a certain part. You can also map out angles, converting deltas to angles and comparing from there.

Hope this helps and good luck!

This discussion is preserved as it was. New answers, comments, and votes are closed.