I'm working on a script that displays a "hold e" gui when the player gets close enough to the nearest designated object. When the player is within range, if they press and hold E an animation in the gui plays. After 3 seconds if the player lets go of E, an event is fired that destroys the object.
Here's my problem: after being close enough to the object and begun to hold E, if the player continues to hold e and walks away from the object they can come back to it or a different object and as long as they've held E for 3 seconds the animation will still play and the event will still fire when they let go of E.
I solved half of this problem by telling the script to set the currenttime/tick to nil if the player is not within range, BUT if I also tell the animation to cancel, then the script only works with one of my designated objects and will not work with any others until that object is destroyed.
--> How do make my holding-E tween animation cancel when the player is out of range, without breaking my script? <--
The problem spot is located towards the bottom function of the script:
local inputservice = game:GetService("UserInputService")
local TS = game:GetService("TweenService")
local TI = TweenInfo.new(3,Enum.EasingStyle.Linear, Enum.EasingDirection.Out,0,false,0)
local createAnim = TS:Create(script.Parent.Frame.ProgBar, TI, {Size = UDim2.new(1.1, 0, 0.339, 0)})
wait(2)
inputservice.InputBegan:Connect(function(input) --starts the animation when within range
if input.KeyCode == Enum.KeyCode.E then
for _,frontdoor in pairs(workspace.Destroyables:GetChildren()) do
local Door = frontdoor:FindFirstChild("Destroyer")
if Door ~= nil then
local Mag = (Door.Center.Position-game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude
if Mag <= Door.Range.Value then
createAnim:Play()
currenttime = tick()
break
end
end
end
end
end)
inputservice.InputEnded:connect(function(i,g) -- stops the animation and fires event if within range
if i.UserInputType == Enum.UserInputType.Keyboard then
if i.KeyCode == Enum.KeyCode.E then
for _,frontdoor in pairs(workspace.Destroyables:GetChildren()) do
local Door = frontdoor:FindFirstChild("Destroyer")
if Door ~= nil then
local Mag = (Door.Center.Position-game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude
if Mag <= Door.Range.Value then
if currenttime ~= nil and (tick()-currenttime) >= 3 then
Door.Event:FireServer()
createAnim:Cancel()
script.Parent.Frame.ProgBar.Size = UDim2.new(0, 0, 0.339, 0)
currenttime = nil
else
createAnim:Cancel()
script.Parent.Frame.ProgBar.Size = UDim2.new(0, 0, 0.339, 0)
currenttime = nil
end
break
end
end
end
end
end
end)
while true do -- makes the Gui visible when the nearest designated object is in range
script.Parent.Frame.Visible = false
for v, frontdoor in pairs(workspace.Destroyables:GetChildren()) do
local Door = frontdoor:FindFirstChild("Destroyer")
if Door ~= nil then
local Mag = (Door.Center.Position-game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude
if Mag <= Door.Range.Value then
local D3ToD2 = workspace.CurrentCamera:WorldToScreenPoint(Door.Center.Position)
script.Parent.Frame.Visible = true
script.Parent.Frame.Position = UDim2.new(0,D3ToD2.X,0,D3ToD2.Y,0)
break
else
currenttime = nil -- this one works fine to stop the time part
createAnim:Cancel() -- including this command ruins the script and causes it to only work one object (but the gui is still visible when I get close enough to another one)
end
end
end
wait()
end
