I’m trying to prevent the player from dying and instead they just get ‘downed’ when their health reaches 0. There was a post similar to this, which I tried, and it works okay
But the main problem is that say for example, the player had 5HP left, but the incoming dmg was 10, it would kill them and trigger the down property after
Edit: I changed the named to make it easier to find for people making a grip system.
I tried this and it seemed pretty good, but it didn’t work. The thing I can’t overcome is the character taking the entire instance of damage, because it can’t be taken in parts
You can actually set the state Enum.HumanoidStateType.Dead enabled to false, however, you need to do it in both the server and client for it to work. You can do something like this:
ServerScriptService Script
--!strict
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ToggleDeathRemote: RemoteEvent = ReplicatedStorage.ToggleDeath -- path to RemoteEvent
local function ToggleDeath(player: Player, toggle: boolean): ()
local humanoid: Humanoid? = if player.Character ~= nil then player.Character:FindFirstChild("Humanoid") :: Humanoid else nil
if player.Character ~= nil and humanoid ~= nil then
humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, toggle)
ToggleDeathRemote:FireClient(player, toggle)
-- You may want to toggle the health regeneration script as well
local healthScript: Script? = player.Character:FindFirstChild("Health") :: Script
if healthScript ~= nil then
healthScript.Disabled = not toggle
end
end
end
-- If you automatically want to disable the death state upon spawning
local function onCharacterAdded(character: Model): ()
local player: Player = Players:GetPlayerFromCharacter(character)
ToggleDeath(player, false)
end
local function onPlayerAdded(player: Player): ()
player.CharacterAdded:Connect(onCharacterAdded)
if player.Character ~= nil then
task.spawn(onCharacterAdded, player.Character)
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
StarterPlayerScripts LocalScript
--!strict
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Player: Player = Players.LocalPlayer
local ToggleDeathRemoteEvent: RemoteEvent = ReplicatedStorage.ToggleDeath -- path to RemoteEvent
local function onToggleDeath(toggle: boolean): ()
local humanoid: Humanoid? = if Player.Character ~= nil then Player.Character:FindFirstChild("Humanoid") :: Humanoid else nil
if humanoid ~= nil then
humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, toggle)
end
end
ToggleDeathRemoteEvent.OnClientEvent:Connect(onToggleDeath)
Do note that this also essentially breaks the Reset callback. You would need to re-enable the state in both the server and client again. To do that, you can do something like this:
ServerScriptService Script
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ResetRemote: RemoteFunction = ReplicatedStorage.Reset -- path to RemoteFunction
local function onReset(player: Player): ()
local humanoid: Humanoid? = if player.Character ~= nil then player.Character:FindFirstChild("Humanoid") :: Humanoid else nil
if player.Character ~= nil and humanoid ~= nil then
-- Set state before forcefully killing
humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, true)
-- Force kill player
humanoid:ChangeState(Enum.HumanoidStateType.Dead)
humanoid.Health = 0
end
end
ResetRemote.OnServerInvoke = onReset
StarterPlayerScripts LocalScript
--!strict
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterGui = game:GetService("StarterGui")
local Player: Player = Players.LocalPlayer
local ResetRemote: RemoteFunction = ReplicatedStorage.Reset -- path to RemoteFunction
local ResetBindable: BindableEvent = Instance.new("BindableEvent")
local function onResetCallback(): ()
local humanoid: Humanoid? = if Player.Character ~= nil then Player.Character:FindFirstChild("Humanoid") :: Humanoid else nil
if humanoid ~= nil then
-- Very important that we set the state back to enabled on our client before asking the server to kill us
humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, true)
-- There are times where the character would not completely "die" after x amount of seconds or if there is
-- a manual physics update. We wait for the server to completely kill us and force an update on the
-- client as well, just in case
ResetRemote:InvokeServer()
humanoid:ChangeState(Enum.HumanoidStateType.Dead)
humanoid.Health = 0
end
end
ResetBindable.Event:Connect(onResetCallback)
-- Repeat until ResetButtonCallback has been registered
local success: boolean = false
while success == false do
success = pcall(StarterGui.SetCore, StarterGui, "ResetButtonCallback", ResetBindable)
if success == false then
task.wait(0.1)
end
end
For people who may see this in the future I’ve made eaterblock’s 's post the solution since it’s simpler, but I suggest reading this one too, to understand clients and servers.