Hello! I want the gui to tween as the person hold on to the space button something like this
however, when I did it it only tweened when I released the space button as shown below. What is the problem here?
This is my code for the tween
local frame = script.Parent
while true do
task.wait()
local value = script.Parent.Parent.Parent.Parent.animation.time.Value
local yaxis = -value*0.25
frame:TweenSize(UDim2.fromScale(1,yaxis),Enum.EasingDirection.Out,Enum.EasingStyle.Sine)
end
the code on how I got the time value
local userinputservice = game:GetService("UserInputService")
userinputservice.InputBegan:Connect(function(button)
if button.KeyCode == Enum.KeyCode.Space then
local timestart = tick()
script:SetAttribute("Time",timestart)
local player = game.Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
humanoid.JumpPower = 0
end
end)
userinputservice.InputEnded:Connect(function(button)
if button.KeyCode == Enum.KeyCode.Space then
local timeend = tick()
local timetaken = timeend-script:GetAttribute("Time")
print(timetaken)
if timetaken <= 4 then
script.time.Value = timetaken
else
script.time.Value = 4
That happens because you are only setting your time value once the input ends. To replicate the behavior that you showed in the first video, you would have to go with a different approach. Instead of playing the tween once the input ends, make the tween play when you start the input and stop the tween when the input ends. This way, your tween will play right as you start pressing the space bar, and it will stop accordingly. If you need help implementing that, let me know; I’ll be happy to help. Here are some resources on the docs you might refer to:
Tween Pausing:
Similar question on the dev forum:
Also please avoid using while true loops, especially for checking something constantly. Make use of events. That is why they exist.
As I said you can play the tween on input began and end it on input ended. You have 2 events built-in to detect when the input starts/ends. This way you don’t need any loops to check when you should play it or not. Simply make the tween play at a constant speed whenever you hit space (input began event), and then pause it when you stop hitting space (input ended event). To calculate time you can refer to the post I sent above, it is pretty much the same as you do, just make the tween play/pause accordingly. You shouldn’t rely on tweens to calculate the time, it would just get messy.
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(4) -- set to the duration you want
local tween = nil -- initializing the variable
UserInputService.InputBegan:Connect(function(button)
if button.KeyCode == Enum.KeyCode.Space then
local timestart = tick()
script:SetAttribute("Time",timestart)
--[[ i wouldn't really recommend doing this, but if you want to do it make sure on input ended you correct the jump power back to what it was
local player = game.Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
humanoid.JumpPower = 0
]]
tweenGoal = {Position = UDim2.new(0, 0, 1, 0)} -- replace with the actual values of your UI, it can be different for you.
tween = TweenService:Create(script.Parent, tweenInfo, tweenGoal) -- make the tween and play it
tween:Play()
end
end)
UserInputService.InputEnded:Connect(function(button)
if button.KeyCode == Enum.KeyCode.Space then
tween:Pause() -- pause the tween we made
local timeend = tick()
local timetaken = timeend-script:GetAttribute("Time")
print(timetaken) -- do whatever you want with it later
end
end)
Do keep in mind that this is the simplest implementation, it might require more stuff depending on your needs, also it would be good to check if the tween exists in the first place, but that’s another problem of programming and you shouldn’t worry about it. (you might refer to it as sanity or nil checks)
Also again the time here doesn’t play any role, you can’t make the size proportional to how long you hold by using tick(). You can do it with the way I suggested, simply play the tween and let it go, if the user let’s go of the space bar earlier than the tween has ended then you pause it and it will be in the exact position the player stopped pressing space. If the user let’s go after it ended it wouldn’t matter, the bar will be full.
local frame = script.Parent
game:GetService("RunService").RenderStepped:Connect(function(deltatime) -- faster and better
local value = script.Parent.Parent.Parent.Parent.animation.time.Value
local yaxis = -value*0.25
frame.Size = frame.Size:Lerp(UDim2.fromScale(1,yaxis),deltatime)
end)
Then simply implement everything else the way you want, that code was just an example of how you can play the tween on inputbegan and pause it on inputended. Also @NoxhazeI you are right that renderstepped might be faster, but it still isn’t practical, why do we have to run a whole renderstepped for a simple task that can be implemented with the use of events? That is just a waste. Events exist, it’s apart of the golden rules of programming. Whenever you can always avoid for loops, while loops or if statements. If you can implement something without using those then do it that way, it’s more practical and effective. I’m not saying never use those, I’m saying try to avoid them and only use it when you can’t do it in a different way. For example trying to listen for a change in a variable is pretty hard and isn’t well supported by the API.
It basically is a loop that runs the code every single frame. DeltaTime is the time period between each frame. And I am using Lerp because its more smoother and has the tween style you need.
RunService is more performant friendlier than events and while loop.