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

Spinning Algorithm: How do I do it?

I'm trying to make a function that will spin a brick 360 degrees in a given amount of time. Or, an explanation in code:

function SpinBrick(Time)
	--Spin the brick 360 degrees in *Time* seconds.
end

I tried making a function that calculated how much the brick needed to spin per second by dividing the circumference of its spin by Time, but I ran into another problem: How many times do I need to iterate the spin distance to reach 360 degrees? In the end, I couldn't figure it out.

How do I make a function that spins a brick 360 degrees in a given amount of time?

2 answers

✓ Accepted answer

Instead of trying to wait a particular amount of time for each iteration, we can just wait as quickly/often/short as possible and figure out, based on the current time, how far along we should be.

E.g., if we're 8.2 seconds through a 10 second duration, we should be at 82% a full revolution.

Equivalently, if before we were at 8.2 seconds of 10, and we got to 8.3 seconds of 10, then we moved forward 1% in time; so we should rotate 1% of a full revolution.


-- for some `brick` a Part
-- for `duration` in seconds

function spin(duration)
	local time = 0
	local totalAngle = math.pi * 2 -- One full rotation

	local startCFrame = brick.CFrame
	-- Where the brick started
	-- (See after loop)

	while time < duration do
		local deltaTime = wait();

		local deltaPercent = deltaTime / duration

		local deltaAngle = totalAngle * deltaPercent
		-- "Unit conversion"

		brick.CFrame = brick.CFrame * CFrame.Angles(0, deltaAngle, 0)

		time = time + deltaTime
		-- Keep track of how much time is left
	end
	brick.CFrame = startCFrame
	-- Since we aren't exactly on
	-- in iteration count, we want to make sure it didn't get
	-- really slightly off.
end

Unfortunately, there is no actual way to get an exact time and Roblox does not offer any method of waiting a specific set of milliseconds (meaning that you can not get an exact time).

Your best option would be to use a for loop that rotates the brick a small amount and waits a fixed amount depending on your iterations (360) and the time you want to achieve (like you said, but in reverse, you divide the time by the circumference).

function SpinBrick(Time)
	local waitTime = Time / 360
	for i = 1, 360 do
		Brick.CFrame = Brick.CFrame * CFrame.Angles(0, math.rad(1), 0)
		wait(waitTime)
	end
end

If you need to get a closer accuracy, you will need to lower the amount of interactions by increasing the for loops increment (for i = 1, 360, 10) and by lowering the circumference in the division of the waitTime (Time / 36 due to 360 / 10 = 36).

3 comments

0

Be careful; this implicitly requires that Time be at least 12 seconds (because wait can't wait quickly enough).

0

Is there a way to make it spin faster? For my needs, the spinner has to accelerate.

0

You could either set the radians increment to a higher value every interation within the loop using a variable, or by decreasing the time every interation. How you go about this really depends on the effect you want to achieve. It may be worth looking into interpolation algorithms for this purpose.

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