Get a 'health' bar for certain models to last periods of time with removing early

Please note, theres no errors, etc. Nothings broken per say, I just want to be able have the health ui stay a little longer when hitting the block. basically, if I hit the tree, UI should appear, and last 3 seconds. If I stop there, UI will disappear. If I keep hitting the tree however, it should continue staying there

Hit:FireServer(Model)
			
if Model.PrimaryPart:FindFirstChild('Status') then
	Model.PrimaryPart.Status.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
else
	local StatusClone = Status:Clone()
	StatusClone.Parent = Model.PrimaryPart
	StatusClone.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)

	Debris:AddItem(StatusClone, 3)
end

robloxapp-20200128-2045028

As you can see, it disappears, even tho Iā€™m still clicking (this is because after the first click it stays for 3 seconds) Ineed it stay for 3 seconds up to the most recent click

Thatā€™s because you fire the else command the first time you break it, meaning that it will break in 3 seconds, I recommend debounce

Iā€™m not trying to prevent the player from clicking multiple times. I already use debounce. Not sure what you are talking about ā€˜breakā€™, nothings breaking. The UI is being destroyed.

No, i mean a debounce for the tree:

What I mean:

Hit:FireServer(Model)
local db = false
function db()
    if db = true then
        wait(3)
        db = false
    end
end
db = true
db()
if Model.PrimaryPart:FindFirstChild('Status') then
	Model.PrimaryPart.Status.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
else
	local StatusClone = Status:Clone()
	StatusClone.Parent = Model.PrimaryPart
	StatusClone.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
    if db = false then
	Debris:AddItem(StatusClone, 0)
end
end

Something along those lines

Why do I need all thatā€¦ thereā€™s no need for that. Iā€™m talking about the GUI, not the tree. This has nothing to do with the tree

you want to delete the gui 3 seconds after the last tree hit, right?
Thatā€™s why I put the debounce in. So it destroys it in 3 seconds

I already have a debounce in the script. I donā€™t want to have/use two

Hey, youā€™ve never tried the actual script I sent, so you donā€™t know if it works or not. This is technically not a debounce for the breaking part of the tree, but the destroying of the UI

Just did, didnā€™t work
30 characters

you need to reset the 3 second counter if you click again

Something like this

local t = 0			
if Model.PrimaryPart:FindFirstChild('Status') then
	Model.PrimaryPart.Status.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
	t = 0
else
	local StatusClone = Status:Clone()
	StatusClone.Parent = Model.PrimaryPart
	StatusClone.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
	t = 0
	while t < 3 do	
		t = t + wait(.05)
	end
	StatusClone:Destroy()
end
2 Likes

Does not work

local Time = 0
	
	if Part then
		local Model = Part.Parent
		if Model then
			Hit:FireServer(Model)
			
			if Model.PrimaryPart:FindFirstChild('Status') then
				Model.PrimaryPart.Status.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
				Time = 0
			else
				local StatusClone = Status:Clone()
				StatusClone.Parent = Model.PrimaryPart
				StatusClone.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
				
				Time = 0
				
				while Time < 3 do	
					Time = Time + wait(0.05)
				end
				
				StatusClone:Destroy()
			end
		end
	end

The bar doesnā€™t move. It stays static, until the frame gets destroyed. And even if I continue clicking, it still gets deleted after 3 seconds (not 3 seconds after last click)

Everytime you click the tree, reset a timer value to 0 and just keep setting that value to tick(). If tick()-value is greater than or equal to 3, then destroy the gui, if it exists. (edited oopsie)

oops, you need to put the while loop in a spawn() function like so

spawn(function()
     while t > 3 do
           t = t + wait(.05)
     end
end)

I kinda misunderstood how you were doing it. I suggest you :FireServer(), update the values on the server, and then :FireClient() to the player who :FireServer()'d. OnClientEvent should handle the guis. This should stop you from having to create another thread in the script

local counter = 0
local debounce = false
local function StartCounting()
   counter = 3

  -- wrap next bit in debounce so itā€™s running a maximum of one time concurrently 
  while counter > 0 do
    wait(1)
    counter = counter - 1
  end

  GUI:Destroy()
end

Call the function every time the action happens. The count variable will keep getting reset to 3. The while loop runs infinitely until the counter hits 0, at which point the block ends and the gui is destroyed.

Still not 100% working. The UI disappears and then quickly reappears.

As for remove event returning to client, I dont wanna do that, as usually theres a whole second, sometimes longer between it coming back to the client. I want instant.

I faced the similar issue recently.
You may need to touch the script a bit deeper.

My workaround in 2 steps:
1)

  • add a numeric ā€œLifeTimeā€ value to Status object, with default value 3 (sec)
  • add a ā€œself-destructionā€ script to Status object, that monitors if the time since the object spawn (in tick()) elapsed more than the value stored in LifeTime. If yes, destroy the object.
  • when you clone the Status object, enable the script.
    If nothing happens after cloning the object (as described above), the object will be destroyed after 3 sec.
  • when you hit the Model (tree) for the first time, clone the Status object and save the tick() to a variable (e.g. ā€œtā€)
  • whenever you hit the Model (tree) again during the lifetime of the cloned Status object, add the difference of the current tick() and the saved value (ā€œtā€) to the Status clone ā€œLifeTimeā€ value. It will keep your Status bar lasts exactly as long as you wished.

It should work.
(I canā€™t write and test a code right now, but I solved it in this way.)

Hit:InvokeServer(Model)
			
			local Time = tick()
			MostRecentCall = Time
			
			if Model.PrimaryPart:FindFirstChild('Status') then
				if Model and Model.Parent then
					Model.PrimaryPart.Status.Frame.Bar:TweenSize(UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Linear, 0.1, true)
				end
			else
				local StatusClone = Status:Clone()
				StatusClone.Parent = Model.PrimaryPart
				StatusClone.Frame.Bar.Size = UDim2.new(Model.Durability.Value / Model.HP.Value, 0, 1, 0)
				
				spawn(function()
					wait(3)
					if Time == MostRecentCall then	
						StatusClone:Destroy()
					end
				end)
			end

Got it so close. It doesnā€™t disappear when I keep clicking, however, it just doesnā€™t disappear at all now

Ok, here are the codes, I tested it and it works.

I used a Part with a ClickDetector + child SurfaceGui/TextLabel, but the logic is the same as your Model / Statusbar.
lifeTime is a NumberValue object, child of the TextLabel (default value can be any).
Make SurfaceGui Disabled by default.

  1. Hit script (fires when you click on the part):

     part = script.Parent.Parent
     label = part.SurfaceGui.TextLabel
     local t
     	
     part.ClickDetector.MouseClick:Connect(function()
    
     if not part.SurfaceGui.Enabled then
     	part.SurfaceGui.Enabled = true
     	label.lifeTime.Value = 3
     	label.selfdestructScript.Disabled = false
     	t = tick()
     	else
     	label.lifeTime.Value = label.lifeTime.Value + tick() - t
     	t = tick()
     end
    

    end)

  2. Self-destruction script (a child of the TextLabel, make it Disabled by default)

    local spawnTime = tick()
     while tick()-spawnTime < script.Parent.lifeTime.Value do
          wait()
     end
     script.Parent.Parent.Enabled = false
     script.Disabled = true

Can you format the code so it makes a little senseā€¦