Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Creating a smooth delay instead of a choppy one?

Asked by 7 years ago
Edited 7 years ago
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

Log in to vote
1
Answered by
BlackJPI 2658 Snack Break Moderation Voter Community Moderator
7 years ago

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
Ad

Answer this question