HealthChanged firing multiple times. How do I make it fire only once?

Greetings. I have made a stagger system that cuts a player’s health in half when they take damage and then resets it back to its original speed.

It works, but has a strange problem. It fires multiple times for some reason. The player has their speed cut in half, it resets, then the player’s speed is cut again and it is reseted, this happening multiple times until finally stopping. The repetition seems to occur consistently, but I have been unable to get rid of it.

The script is located inside the player’s character. Here is the code:

Humanoid = script.Parent:FindFirstChildOfClass("Humanoid")
CurrentHealth = script.Parent:FindFirstChildOfClass("Humanoid").Health

function HealthChanged(Remaining)
	local PreviousSpeed = Humanoid.WalkSpeed
	if Remaining < CurrentHealth and Humanoid.WalkSpeed == PreviousSpeed then
		local value = Humanoid.WalkSpeed / 2
		Humanoid.WalkSpeed -= value
		task.wait(0.25)
		Humanoid.WalkSpeed += value
	end
end

script.Parent:FindFirstChildOfClass("Humanoid").HealthChanged:connect(HealthChanged)
3 Likes

After adding a print() to the function, I have noticed that the effect repeats itself based on the exact number of damage the player has received. For example, if a player takes 5 damage, the process occurs 5 times.

I would like to know how to stop this repetition from occurring. Adding a debounce does not seem to help.

1 Like

Replacing HealthChanged:connect with HealthChanged:once makes it fire only once, but then the function does not occur the next time the player takes damage. I have yet to find a solution.

1 Like

Still can’t seem to get it to work as intended. I will keep it disabled for now and resume when I ever discover a solution.

1 Like

Create a debounce / delay, so when it fires the first time, set a variable to true then wait out the time the stagger should last, then set it to false.

2 Likes

It might be the Health script that is healing you.

1 Like

Create a debounce / delay, so when it fires the first time, set a variable to true then wait out the time the stagger should last, then set it to false.

I did that. It did not solve the problem.

It might be the Health script that is healing you.

It is not. The script checks if the damage has been reduced and not increased.

1 Like

Perhaps there is no way of doing this through this method. I will see if I can find an alternative. It’s a shame such a simple method is apparently not doable due to this strange flaw.

1 Like

Both of these suggestions are relevant.

Adding a debounce will prevent the effect from stacking if the player takes damage multiple times in rapid succession, although if you’re fine with that, then a debounce isn’t necessary.

While your code checks if the remaining health is less than the current health before applying the walkspeed change, the value is never updated, so healing the player will still trigger the effect if the Humanoid is still at a lower health amount than it was at when the script initialized.

The following code implements both changes:

local Humanoid = script.Parent:FindFirstChildOfClass("Humanoid")
local CurrentHealth = script.Parent:FindFirstChildOfClass("Humanoid").Health

local Active = false

function HealthChanged(Remaining)
	local TookDamage = Remaining < CurrentHealth
	CurrentHealth = Remaining
	
	if not Active and TookDamage then
		Active = true
		
		local value = Humanoid.WalkSpeed / 2
		Humanoid.WalkSpeed -= value
		task.wait(0.25)
		Humanoid.WalkSpeed += value
		
		Active = false
	end
end

script.Parent:FindFirstChildOfClass("Humanoid").HealthChanged:connect(HealthChanged)
3 Likes

I was sure both these issues were checked out, but it seems my implementation was improper seeing as your take on implementing them worked better than mine. The script works just as intended with your fixes. Thank you very much

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.