Making a rotate tool

Hello, I am trying to make a rotate tool like ROBLOX studio rotate tool, but in-game.

I am not exactly sure where to begin.

I know I need ArcHandles in the player gui with adornee set to the part. I know to use MouseDrag event, my question, what do I put in the event?


A post was merged into an existing topic: Off-topic and bump posts

Are you trying to replicate Roblox Studio’s rotation exactly? If so there are plenty of tools that do this already that are available to use.


I just want to know how this is done using the mouseDrag event.

1 Like

Hello there!

There are plenty of free-modeled rotate tools you can take a look at and see how you can implement one of these systems.

The first parameter of the MouseDrag event is the axis that the player dragged their mouse on. The second one is just the RelativeAngle (which has no wiki documentation so I don’t know what it is) so you can just use if statements and detect which axis they dragged on and then you can perform CFrame operations on them using basic math.

I created a quick prototype in studio to test this system out and it works pretty neat. (It’s in a local script in StarterGui, this is just a demonstration, it won’t work in FilteringEnabled)

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local increment = 5

local lastCFrame = nil

function round(number)
	return math.floor((number / increment) + 0.5) * increment
function AngleFromAxis(axis, r)
	local relativeAngle = math.rad(round(math.deg(r)))
	return axis == Enum.Axis.X and {relativeAngle, 0, 0} 
		or axis == Enum.Axis.Y and {0, relativeAngle, 0} 
		or axis == Enum.Axis.Z and {0, 0, relativeAngle}

script.Parent.ArcHandles.MouseDrag:Connect(function(axis, relativeAngle, delta)
	workspace.Part.CFrame = lastCFrame * CFrame.Angles(unpack(AngleFromAxis(axis, relativeAngle)))
	lastCFrame = workspace.Part.CFrame

Feel free to ask any questions you may have!


How can I use an increment? Would I like find the distance rotated and divide it increment and round it to the increment?

1 Like

Please do not bump post. Contain all your commentary in as little replies as possible and edit them if you have any information to add.


You can just implement a function that rounds the value.

function round(number, increment)
	return math.floor((number/increment)+0.5) * increment
1 Like

What do I put for number?

1 Like

You would put in the RelativeAngle parameter from the MouseDrag event.

I would advise you to take a look at free modeled rotate tools so you can see how they work.

1 Like

@AdvancedDrone Where do I call the function within this line

CFrame.Angles(math.rad(math.sin(relativeAngle)) * 2, 0, 0)

1 Like

Whoops! I made a mistake with the code, I fixed it in the reply I made earlier.

Instead of doing what I did before, you should set the LastCFrame of the part and then just multiply it by CFrame.Angles with the rounded input.

The example code should work now, let me know if you still have any questions.

1 Like
CFrame.Angles(math.rad(math.sin(round(relativeAngle))) * 2, 0, 0)
1 Like

@AdvancedDrone I had a feeling you had to use something like lastCframe, anyway it works 10x better. But increment still does not work correctly, did it work for you?

1 Like

A proposal to increment is to use a delta and compare it against your increment.

Your delta would be the CFrame minus last CFrame then by getting the absolute value of that and comparing if its greater than or equal to the increment.

Sorry this is a year late reply Lol.


I suggest to use “script.Parent.ArcHandles.Adornee” instead of the “workspace.Part”, but anyway this is a really nice script, ty for sharing!

1 Like

Increment becomes glitchy after the increment is 23

1 Like