Knocked System Not working

hello im trying to make a knocked system where if a player is below or equal to a certain health they will be knocked out (down). but for some reason my script is bugging out. the knocked part works but then some times the regain health function stops working or it will break (not work) when the regain health function is running and the player takes damage. Could the reason be that i already have another local script that operates another separate function when the player looses health?

– local script in starterPlayerScripts for Knocked System

-- Define events and player
local carryEvent = game.ReplicatedStorage:WaitForChild("Carry")
local gripEvent = game.ReplicatedStorage:WaitForChild("Grip")

local player = game:GetService("Players").LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

-- Wait for the character to load
repeat wait() until char

print("char loaded")

-- Get the Humanoid object
local hum = char:WaitForChild("Humanoid")

-- Set initial attributes
char:SetAttribute("Knocked", false)
char:SetAttribute("IsKnocked", false)
char:SetAttribute("CanCarry", true)

-- Define health-related variables
local knockedHealth = 5
local getBackUpHealth = 10
local healthTime = 1
local healBy = 1

-- Function to regain health over time
local function regainHealth()

	while hum.Health <= knockedHealth and char:GetAttribute("Knocked") do
		
		hum.Health = hum.Health + healBy

		task.wait(healthTime)

		if hum.Health >= getBackUpHealth then
			char:SetAttribute("Knocked", false)
			print("player is back on thier feet")

			break
		end
	end

end

-- Function to handle health changes
local function healthChanged()
	if hum.Health <= knockedHealth then
		char:SetAttribute("Knocked", true)
		print("Player is down")
		regainHealth()
	end
end

hum:GetPropertyChangedSignal("Health"):Connect(healthChanged)




-- Connect the function to the Health changed signal
hum:GetPropertyChangedSignal("Health"):Connect(healthChanged)



– local script in starterGui for healthBar


	local player = game.Players.LocalPlayer
        local character = player.Character or player.CharacterAdded:Wait()
	local humanoid = character:WaitForChild("Humanoid")
	
	humanoid.HealthChanged:Connect(function(Damage)
		local bar = script.Parent.BackFrame.bar
		 bar.Size = UDim2.new(Damage / humanoid.MaxHealth, 0, 1, 0)
end)
1 Like

Deleted my post cause i read your statements wrong. sorry about that.

dont worry about it. thank you though!

First of all regenerating health on the client is not gonna work. If the player takes damage on the server, you have to regenerate the health on the server: doing it on the client will not update it on the server meaning the player is only “visually” regenerating their health.
So first off, I recommend converting your first local script into a server-sided script.

ohhh makes sense makes sense. thanks for the help

how would convert it since i know its a bit hard to get local player from a server script

Local Players = game:GetService(“Players”)

Players.PlayerAdded:Connect(function()
— here you find a new added player
End

this all in term makes sense but wouldnt the script only work when the player joins the game?

You’d use Players.PlayerAdded like @Broskinie mentioned. It’s the only way to get the player correctly in this case.

Once you connect an event, it’s not gonna disconnect until the instance the event was connected to gets destroyed. So if you connect HealthChanged to the Humanoid, that event is not gonna disconnect until the Humanoid is destroyed.

game.Players.PlayerAdded:Connect(function(player)
   player.CharacterAdded:Connect(function(character)
      local hum = character:WaitForChild("Humanoid");
      
      local regenerating = false;
      local function regainHealth()
        if regenerating  == true then return end;
        regenerating  = true;
	    while hum.Health <= knockedHealth and char:GetAttribute("Knocked") do
		
		    hum.Health = hum.Health + healBy

		    task.wait(healthTime)

		    if hum.Health >= getBackUpHealth then
			    char:SetAttribute("Knocked", false)
			    print("player is back on thier feet")
                regenerating  = false;
			    break
		    end
	    end
      end

      local function healthChanged()
	      if hum.Health <= knockedHealth then
		     char:SetAttribute("Knocked", true)
		     print("Player is down")
	   	     regainHealth()
	      end
      end


      hum.HealthChanged:Connect(healthChanged);
   end);
end);

Note that I added the regenerating variable. This is to ensure only one while loop is activated at once. If two or more were to activate, it could create issues as they’d overlap each others and make the character get health back faster than it should.

1 Like

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