Problem with hold tween script

Straight to the point, I made a system where when E is held the SurfaceGUI has a textlabel which gets It’s position tweened down and when it’s at a certain position an event is fired but I am having problem with the tweening part, I want to make a tween function instead of reusing tween all the time but problem is when E is not held no more the tween still continues and doesn’t go back after that.

function Tween(Time, state)
local tweenInfo = TweenInfo.new(
    Time,
    Enum.EasingStyle.Linear,
    Enum.EasingDirection.Out
    )
    
    local tween = TweenService:Create(script.Parent.TextLabel, tweenInfo, {Position = UDim2.new(0, 0, 0.99, 0)})
    
    if state == true then
            tween:Play()
    else
        tween:Cancel()
        script.Parent.TextLabel.Position = UDim2.new(0,0,0,0)

    end
    end
UserInputService.InputBegan:connect(function(Input, GameProcessed)
    if ClosestObject ~= nil then
        if UserInputService:GetFocusedTextBox() == nil then
            
            
        while UserInputService:IsKeyDown(Enum.KeyCode.E) do
                Held = true
                wait()
                if Held == true then
                    local Data = ClosestObject:FindFirstChild("Data")
                    Timer = Data.Time.Value
                    script.Parent.Main.BackgroundTransparency = 0.45
                    Tween(Timer, true)
                    if script.Parent.TextLabel.Position == UDim2.new(0,0,0.99,0) then
                    
                    if Data then
                        local Event = Data:FindFirstChild("Event")
                        if Event then
                        local Offset = (HumanoidRootPart.CFrame.Position-ClosestObject.Center.Position)
                        local ray = Ray.new(ClosestObject.Center.Position, Offset.Unit*Offset.magnitude) 
                        local Wall,Hit = workspace:FindPartOnRayWithIgnoreList(ray,{ClosestObject,HumanoidRootPart.Parent})

                        if Wall then
                            print("wall")
                            else
                                Event.Value:FireServer(Data)
                            end
                        end
                    end
                end
                end
        end
        end
        end
end)

UserInputService.InputEnded:connect(function(Input, GameProcessed)
    if Input.UserInputType == Enum.UserInputType.Keyboard then
        if Input.KeyCode == Enum.KeyCode.E then
            Held = false
            Tween(Timer, false)
            script.Parent.TextLabel.Position = UDim2.new(0,0,0,0)
            script.Parent.Main.BackgroundTransparency = 0
        end
    end
end)

The problem is that when you pass false as the second param it creates a new tween and then cancels that tween:

local tween = TweenService:Create(script.Parent.TextLabel, tweenInfo, {Position = UDim2.new(0, 0, 0.99, 0)})
    
    if state == true then
        tween:Play()
    else
        tween:Cancel() 

it doesn’t cancel the tween that was already made and is currently playing. You can try out this system, have a variable called PlayingTween at the beginning of the script so it’s accessible from everywhere, if state is true then create a new tween and assign it to the PlayingTween variable, and if state is false then cancel the PlayingTween variable.

local PlayingTween 

function Tween(Time, state)
    local tweenInfo = TweenInfo.new(
        Time,
        Enum.EasingStyle.Linear,
        Enum.EasingDirection.Out
    )
    
    if state == true then
        PlayingTween = TweenService:Create(script.Parent.TextLabel, tweenInfo, {Position = UDim2.new(0, 0, 0.99, 0)})
        PlayingTween:Play()
    else
        PlayingTween:Cancel()
        PlayingTween = nil -- wipe the old playing tween from memory
        script.Parent.TextLabel.Position = UDim2.new(0,0,0,0)
    end
end 

I may have messed up because I’m writing this on my phone.

Thank you so much! I been trying to fix this for about 2 days now

1 Like