How do i make a part rotate at a RPM

so if I have a rpm (500 for example) i want to rotate a part in a loop at that speed, but how? i know how to rotate a part just not using RPM for speed

1 Like

I’m not a scripter, but maybe use values, and then tell the script depending on the value, go this fast?

I’m not sure, I hope an actual scripter hops in here and helps you out :grimacing:

The first thing to do here is to convert RPM into either degrees per minute or radians per minute. I’ll use radians per minute because it’s easier to work with later.
1 rpm = 360 degrees per minute = 2*math.pi radians per minute

local rpm = 500
local radsPerMinute = rpm * 2 * math.pi

The next step is to convert that to seconds, since pretty much everything in Roblox is based on seconds. There are 60 seconds per minute, so divide by 60.

local radsPerSecond = radsPerMinute / 60

Then you need to decide how you want to use it. Based on you wording, it sounds like you might want it handled by CFraming the rotation in a loop?

-- keep track of the current rotation
local currentRotation = 0
-- infinite loops don't hurt anyone, contrary to the myths that go around.
-- just don't use a loop like this to wait for an object to exist. use events for that.
while true do
    -- wait using task.wait()
    -- task.wait() returns the seconds that it waited for, very useful for making
    -- exact calculations and compensating for whatever lag might exist.
    -- task.wait() with nothing in the parenthesis waits for about 1/60th of a second,
    -- so this will be about 0.016 depending on how busy and/or laggy your game is.
    local secondsWaitedThisFrame = task.wait()

    -- multiply our radians per second by the seconds waited to get
    -- the amount to rotate during this frame.
    local radsToRotateThisFrame = secondsWaitedThisFrame * radsPerSecond

    -- add that number to currentRotation.
    currentRotation += radsToRotateThisFrame

    -- we don't want current rotation to stack up infinitely because
    -- first, we don't need it to, and second, it may start to glitch out at
    -- really high numbers.
    -- remember elementary school division, how we calculated the remainder instead
    -- of using decimals? so 5/2 resulted in 2 (remainder 1) instead of 2.5?
    -- that's extremely useful in a lot of scenarios in programming, and we're doing
    -- that here. the % sign represents 'modulo', 'modulus', or 'modular division',
    -- depending on who you ask. it gives you the remainder after division.
    -- it's incredibly useful for wrapping numbers around to the beginning.
    -- simply do `yourNumber % maxNumber`.
    -- in our case, the max number is either 360 for degrees or 2*math.pi for radians.
    currentRotation %= 2 * math.pi

    -- let's use CFrames for rotation in this case. make sure you define targetPart.
    -- CFrames represent both position and rotation, and we only want to set rotation.
    -- so let's get the part's current position so that we don't accidentally move it.
    -- CFrame.new(x, y, z) creates a new CFrame at position xyz with no rotation.
    local positionCFrame = CFrame.new(targetPart.Position)

    -- CFrame.Angles isn't always the best thing to use, but it's really easy
    -- to understand and good for simple tasks, so it's what we'll use here.
    -- CFrames always use radians, which is why we chose them.
    -- if you're using degrees, you need to use math.rad(currentRotation)
    -- instead of just currentRotation, in order to convert it to radians.
    -- CFrame.Angles(x, y, z) creates a new CFrame at position 0,0,0 with
    -- the given rotation. right now, currentRotation is taking the place
    -- of the y parameter, so our part will rotate around the y axis.
    local rotationCFrame = CFrame.Angles(0, currentRotation, 0)

    -- to 'add' two CFrames, you multiply them. the reason for this is
    -- behind-the-scenes college-level math called linear algebra, and some people
    -- say that you shouldn't call it "adding". however, it basically just
    -- adds them together so who cares what it's called.
    -- let's "add" the position and the rotation CFrames together.
    -- order matters. if you have the rotation on the left, you're basically rotating
    -- the coordinate system, and then adding the position will make the part
    -- to a different position than you want it to go to. I didn't set myself up
    -- for a good explanation of this and I'm not going to try very hard to explain.
    -- but imagine if we added a CFrame of 5 studs in the Y direction to our
    -- character's position. it would be 5 studs above us.
    -- then we can take that position and add a rotation of 45 degrees forward tilt,
    -- and create a part 5 studs above us rotated 45 degrees forward.
    -- but if we add the rotation to our character's CFrame first, and then
    -- added 5 studs Y, the Y axis would be rotated and our resulting position
    -- would actually be 5 studs above and in front of us at a 45 degree angle.
    -- let me know if you want a better explanation of this and I'll get some
    -- diagrams, but for now this should be good enough. rotating first has as use,
    -- but it's not what we want here.
    local resultCFrame = positionCFrame * rotationCFrame
    
    -- and then apply the result to the part.
    targetPart.CFrame = resultCFrame

end
1 Like

To make a part rotate at a certain RPM, you can use a script that sets the CFrame of the part at a regular interval. Here’s an example script that rotates a part at 60 RPM:

local part = script.Parent -- Change "script.Parent" to the path of the part you want to rotate
local rpm = 60 -- Change this value to the desired RPM

local function rotatePart()
    local cf = part.CFrame
    local rotation = CFrame.Angles(0, math.rad(rpm * 6), 0)
    part.CFrame = cf * rotation
end

game:GetService("RunService").Heartbeat:Connect(rotatePart)

This script sets up a function called rotatePart that calculates the new CFrame of the part based on the current CFrame and a rotation of rpm * 6 degrees around the Y-axis. The rpm * 6 calculation is used because there are 360 degrees in a full rotation, and there are 60 seconds in a minute, so rpm * 6 gives the degrees of rotation per second.

Does this work? I tried it on a part , the script under the part, and it does not rotate. Can you share exploer of how you have it set up and working?
Thanks a bunch

1 Like

This is working just fine.
You may need to adjust the rpm variable, try to set it to 100 as an example.

you should use the deltatime from heartbeat so that the rpm won’t differ at different frame rates.

You can use delta time to improve the performance of this code for users with higher FPS. Delta time is the time between the current frame and the previous frame, and using it in calculations ensures that the code runs smoothly regardless of the FPS.

Here’s an example:

local function rotatePart(deltaTime)
    local cf = part.CFrame
    local rotation = CFrame.Angles(0, math.rad(rpm * 6) * deltaTime, 0)
    part.CFrame = cf * rotation
end

game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
    rotatePart(deltaTime)
end)
2 Likes

Hi,
Cool it works.
Is there a way that when the player is standing on it, and it spins, they also spin? In the test case, it is a simple 4,1,4 block…

Thanks

Create a new topic, and I’ll eventually answer you (unless someone does it before me).

i wouldn’t say it improves the performance.