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

Trying to move a part using DeltaTime, but it speeds up if clicked more than once?

Asked by
Reivani 11
5 years ago

Hi. I'm just trying to make a simple script that will move a part from one point to another after you click a button. I wanted to use RenderStepped to make it as smooth as possible, along with Delta Time to keep it at a constant speed regardless of FPS, however I've ran into multiple issues with it, the first being that the more you click it, the faster it will go, and it will start stuttering. I've tried using debounce to fix this, but it doesn't seem to work. Here's a gif showing the problem.

I did kind of fix one problem I originally had with debounce, which is that the two loops would be played at once, which is what the "lock" variable is for.

Here's the code:

local RunService = game:GetService("RunService")

local partA = workspace.A --point A
local partB = workspace.B --point B
local partC = workspace.C --moving part
local Button = workspace.Button

local speed = 2

local lock = false

Button.ClickDetector.MouseClick:Connect(function()
    RunService.Heartbeat:Connect(function(deltaTime)
        local deltaSpeed = deltaTime * speed
        if lock == false then
            local CFrameLerpA = partC.CFrame:Lerp(partA.CFrame, deltaSpeed)
            partC.CFrame = CFrameLerpA
            wait(5)
            lock = true
            local CFrameLerpB = partC.CFrame:Lerp(partB.CFrame, deltaSpeed)
            partC.CFrame = CFrameLerpB
            wait(5)
            lock = false
        end
    end)
end)

1 answer

Log in to vote
0
Answered by 5 years ago

Hi. There are a couple reasons why this is not creating the desired effect. The first problem is the placement of your debounce on line 19. The reason for this is because on line 15 you wait 5 seconds.If someone were to click the detector in those 5 seconds, the function would think that debounce was still false. This is what is causing the speedup. Secondly, you are connecting heartbeat more than once. Heartbeat will continue to execute every frame until you disconnect it, which you never do. This means that every time someone clicked the detector a new heartbeat connection is made. This is really bad for performance, and after some clicking your game's server will start to lag. You can check the script performance tab to see what I mean. As you keep clicking the Activity % of the script will go up.

A better way of doing this that would have the same effect is using the TweenService. What this does is smoothly transition different properties over time.

local TweenService = game:GetService("TweenService");

local partA = workspace.A --point A
local partB = workspace.B --point B
local partC = workspace.C --moving part
local Button = workspace.Button

local speed = 2

local lock = false;

local TweenDetails = TweenInfo.new(
    5,
    Enum.EasingStyle.Linear,
    Enum.EasingDirection.In,
    0,
    false,
    0
); -- feel free to play with these properties

local function Unlock()
    lock = false;
end

local function Tween2()
    local TweenProperties = {
        ["CFrame"] = partB.CFrame
    };

    local Tween = TweenService:Create(partC, TweenDetails, TweenProperties);
    Tween:Play();
    Tween.Completed:Connect(Unlock);
end

Button.ClickDetector.MouseClick:Connect(function()
    if lock == false then
        lock = true;

        local TweenProperties = {
            ["CFrame"] = partA.CFrame
        };

        local Tween = TweenService:Create(partC, TweenDetails, TweenProperties);
        Tween:Play();
        Tween.Completed:Connect(Tween2);
    end
end)

However if you are insistent on making the original script work, I have fixed it here.

local RunService = game:GetService("RunService")

local partA = workspace.A --point A
local partB = workspace.B --point B
local partC = workspace.C --moving part
local Button = workspace.Button

local speed = 2

local lock = false;
local HeartbeatFunction;

local function CtoA(deltaTime)
    local deltaSpeed = deltaTime * speed
    local CFrameLerpA = partC.CFrame:Lerp(partA.CFrame, deltaSpeed)

    partC.CFrame = CFrameLerpA
end

local function CtoB(deltaTime)
    local deltaSpeed = deltaTime * speed;
    local CFrameLerpB = partC.CFrame:Lerp(partB.CFrame, deltaSpeed)
    partC.CFrame = CFrameLerpB
end

Button.ClickDetector.MouseClick:Connect(function()
    if lock == false then
        lock = true; -- immediately lock
        HeartbeatFunction = RunService.Heartbeat:Connect(CtoA);
        wait(5);
        HeartbeatFunction:Disconnect(); --disconnect so doesn't lag later
        HeartbeatFunction = RunService.Heartbeat:Connect(CtoB);
        wait(5);
        HeartbeatFunction:Disconnect(); --disconnect so doesn't lag later
        lock = false;
    end
end)

Let me know if these don't work or you have further questions.

0
Thank you so much! Both of them worked perfectly! Reivani 11 — 5y
0
No problem. Glad I could help! GrandpaScriptin 148 — 5y
Ad

Answer this question