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

Creating a smooth delay instead of a choppy one?

game["Run Service"].RenderStepped:connect(function(dt)

		local x = mouse.X - maingui.AbsolutePosition.X;
		local y = maingui.AbsolutePosition.Y - mouse.Y;
		
		wait(.25) -- To add a delay
		maingui.Rotation = 90 - math.deg(math.atan2(y, x));
		
end);

I want to create a delay between the gui rotation and the mouse movement, but when you put the wait it feels choppy and not smooth enough, I tried using RenderStepped the Rotation is smoothered out but when you add the wait() to delay the movement it still gets choppy. Any idea on how to make it smoother?

Whitout Delay : https://gyazo.com/55fb397d58d7a9c560bb173a327b4403

With Delay: https://gyazo.com/46617240061c0b31e0c26b8076bf3868

1 answer

✓ Accepted answer

The solution that I came up with doesn't deal with a delay, but rather by giving the GUI a minimum and maximum rotation speed. The speed of the GUI is calculated by a ratio of how much rotation is needed to get to the desired angle. The speed is then multiplied by the elapsed time since the last update to calculate the distance the GUI needs to rotate. The formula for this is as follows:

maxSpeed*(dist + minSpeed)/(180 + minSpeed)

Everytime the mouse is moved, I update the desired angle. The infinite while loop is in charge of updating the GUI. It works using a delta time loop, updating every render frame. In order to rotate to the desired angle, we need to determine if we should rotate clockwise (negative) or counter-clockwise (positive). Once the direction is known, we find the distance we need to rotate this render frame and apply it to the GUI.

When the desired Rotation is reached, we wait for the mouse to move before trying any more updates. This is so we don't waste any computations.

Full Code:

local RunService = game:GetService("RunService")

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local frame = script.Parent -- GUI that should rotate

local maxSpeed = 360 -- deg/sec
local minSpeed = 15 -- deg/sec
local desiredAngle = 0

mouse.Move:connect(function()
	local center = frame.AbsolutePosition + frame.AbsoluteSize/2
	local x = mouse.X - center.X
	local y = center.Y - mouse.Y
	desiredAngle = 90 - math.deg(math.atan2(y, x))
end)

while true do
	local lastTick = tick()
	repeat
		RunService.RenderStepped:Wait()
		local elapsed = tick() - lastTick
		
		-- Calculate turn direction
		local cw = (frame.Rotation - desiredAngle)%360
		local ccw = ((desiredAngle + 360) - frame.Rotation)%360
		if cw < ccw then
			frame.Rotation = frame.Rotation - math.min(maxSpeed*((cw + minSpeed)/(180 + minSpeed))*elapsed, cw)
		else
			frame.Rotation = frame.Rotation + math.min(maxSpeed*((ccw + minSpeed)/(180 + minSpeed))*elapsed, ccw)
		end
		
		lastTick = tick()
	until math.abs(frame.Rotation%360 - desiredAngle%360) < 0.01
	mouse.Move:wait()
end

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