For most circumstances, @1_Lukeskyiwalker is correct that Humanoid.Died
would probably be the best option.
However, depending on your use case, there are a bunch of different events and functions that can be used in order to create what you’re envisioning.
Example #1
For example, if you wanted to add custom behavior when the Character dies (to replace the default functionality of respawning after a few seconds), you could use Humanoid:SetStateEnabled()
to disable the Enum.HumanoidStateType.Dead
state. This would prevent the Character from dying when it reaches 0 Health.
-- (Part 1) Server Script placed into the ServerScriptService
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(Character)
local Humanoid = Character:WaitForChild("Humanoid", 5)
if Humanoid then
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
end
end)
end)
-- (Part 2) LocalScript placed into the "StarterCharacterScripts" container
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
if Humanoid then
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
end
*I originally thought that it was only necessary to call Humanoid:SetStateEnabled()
from the client-side since that’s typically all that is necessary for many of the HumanoidStateTypes
, but during my testing with Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
in particular, I observed the following:
- Only calling it from the server side prevents the player’s Character from being able to naturally respawn after the
RespawnTime
has elapsed.
- However, when you use
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
on the same Character model from both the Client and the Server side, it works as intended, keeping the Character alive even if its Humanoid
reaches 0 Health
.
Example #2
Something else that would be useful to use alongside that would be the Humanoid.HealthChanged
event, which allows you to keep track of every time the Character’s Health
changes.
If you turned off the Enum.HumanoidStateType.Dead
state, you could use this to check when Humanoid.Health
is equal to 0, and when that happens, you’d be able to run the desired code / create a custom animation or effect, etc. to replace the default sequence of the Character breaking apart and respawning after a few seconds.
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(Character)
local Humanoid = Character:WaitForChild("Humanoid", 5)
if Humanoid then
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
--[[
For reasons explained during Example #1,
make sure Humanoid:SetStateEnabled() is also called from
the client / a LocalScript to ensure it works properly
--]]
Humanoid.HealthChanged:Connect(function(newHealth)
if newHealth <= 0 then
-- If the updated Health is 0 or lower...
-- Run desired code / custom functionality
end
end)
end
end)
end)
Example #3
But even if you didn’t turn off any of the HumanoidStateTypes
, the Humanoid.HealthChanged
event could still be used to change something within the game when a Character’s Health is low.
So if you wanted some sort of visual effects on screen, or a debuff to be applied when the Character has less than 25 health, such as decreasing Humanoid.WalkSpeed
, that would be possible. Here’s how you could achieve the latter:
-- Code for a Server Script placed in the ServerScriptService
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(Character)
local Humanoid = Character:WaitForChild("Humanoid", 5)
if Humanoid then
Humanoid.HealthChanged:Connect(function(newHealth)
if newHealth < 10 then
-- If the updated Health is less than 10...
Humanoid.WalkSpeed = 5
warn(newHealth)
elseif newHealth <= 25 then
-- If the updated Health is less than or equal to 25...
Humanoid.WalkSpeed = 10
warn(newHealth)
elseif newHealth > 25 then
-- If the updated Health is greater than 25...
Humanoid.WalkSpeed = 16 -- Default walkspeed
print(newHealth)
end
end)
end
end)
end)
Example #4
If none of the previous examples would work for your use case (or if you want to combine it with something else that can actually predict when a player’s Character is about to reach 0 Health before it happens), then the last solution I can think of at the moment would be to review the Scripts in your game that handle damage (e.g. lava bricks, swords, etc.) and to have the Script calculate what the Character’s Health would be before actually applying the damage.
If it would be 0 or lower after applying the damage, you could have the Script perform another action and / or avoid applying the damage entirely if it’s necessary for the Character to remain in-tact for the feature you’re trying to create (for example, cutscenes where the Character model would need to be present).
local Players = game:GetService("Players")
local lavaBrick = script.Parent
local damage = 10
local debounce = false
lavaBrick.Touched:Connect(function(otherPart)
if debounce then return end
debounce = true
local model = otherPart:FindFirstAncestorOfClass("Model")
if not model then return end
local player = Players:GetPlayerFromCharacter(model)
if not player then return end
local Humanoid = model:FindFirstChildOfClass("Humanoid")
if not Humanoid then return end
local currentHealth = Humanoid.Health
local updatedHealth = Humanoid.Health - damage
if updatedHealth <= 0 then
warn("The Character is about to be at 0 Health!")
-- Run desired code here before applying damage to the Humanoid
--[[ Or you could use this to avoid applying damage to the Humanoid
(by adding an "elseif" statement here to only apply damage if the
"updatedHealth" is greater than 0) so that you could fully rely on
the custom functionality of your choice without making the
player's Character automatically respawn
--]]
end
Humanoid.Health -= damage
print(updatedHealth)
task.wait(0.5)
debounce = false
end)