Assistance required for floating Ragdolls ( considered alive with 0 health? )

Hello,
I’m actually having issues with rag dolls for my game. I am trying to make so that when someone dies, it goes in rag doll. But they are actually floating 1/4 times. It is like the health is equal to zero but the humanoid is still alive. I am forced to clone the rag doll to make a different instance. But when they are created, there is 25 percent of chances to have floating rag dolls.

I have tried many things so far… Creating a loop to set health to 1 and then back to 0 to try to kill the humanoid… I tried to ChangeState instead of changing the Health… I even did both… I even tried to SetNetworkOwner of all the base parts to the server… It reduced the chances of the bug to happen.

Here are two photos of the bug:
screenshot 1
screenshot 2

Here is problematic piece of code.


function pnil(player : Player)
	player.TeamColor = BrickColor.new("Institutional white")
	if player.Character then
		player.Character:Destroy()
		player.Character = nil
	end
	wait(game.Players.RespawnTime)
	if not player.Character and player.TeamColor == BrickColor.new("Institutional white") then
		game:GetService("ServerStorage"):WaitForChild("BindEvents"):WaitForChild("Reseti"):Invoke(player, true)
	end
end
-- Many things between this but I won't post all the code.
RagDollFunc.OnInvoke = function(plr)
	if not isAllowed(plr) then
		return
	end
	if plr.Character == nil then
		return
	end
	plr.Character.Archivable = true
	local Char = plr.Character:Clone()
	plr.Character.Archivable = false
	plr.Character.Parent = nil
	if Char:FindFirstChild("CrouchValue") then
		Char:FindFirstChild("CrouchValue"):Destroy()
	end
	if Char:FindFirstChild("Fax") then
		Char:FindFirstChild("Fax"):Destroy()
	end
	if Char:FindFirstChild("C4Back") then
		Char:FindFirstChild("C4Back"):Destroy()
	end
	for i,v in pairs(Char.Humanoid:FindFirstChildWhichIsA("Animator"):GetPlayingAnimationTracks()) do
		v:Stop()
		v:Destroy()
	end
	local h2 = Instance.new("Humanoid")
	h2.Name = "Ragdoll"
	h2.NameOcclusion = Enum.NameOcclusion.NoOcclusion
	h2.BreakJointsOnDeath = false
	local gvelo = Char.Torso.AssemblyLinearVelocity
	Char.Humanoid:Destroy()
	for _, v in pairs(Char:GetDescendants()) do
		if v:IsA("Motor6D") then
			local Att0, Att1 = Instance.new("Attachment"), Instance.new("Attachment")
			Att0.CFrame = v.C0
			Att1.CFrame = v.C1
			Att0.Parent = v.Part0
			Att1.Parent = v.Part1
			local BSC = Instance.new("BallSocketConstraint")
			BSC.LimitsEnabled = true
			BSC.TwistLimitsEnabled = true
			BSC.TwistLowerAngle = -20
			BSC.TwistUpperAngle = 20
			BSC.Attachment0 = Att0
			BSC.Attachment1 = Att1
			BSC.Name = v.Name
			BSC.Parent = v.Part0

			v:Destroy()
		end
	end
	for _, v in pairs(Char:GetDescendants()) do
		if v:IsA("BaseScript") then
			v:Destroy()
		end
	end
	Char.Parent = workspace.Debris
	wait()
	h2.Parent = Char
	--[[
	for _, v in pairs(Char:GetDescendants()) do
		if v:IsA("BasePart") then
			if v:CanSetNetworkOwnership() then
				v:SetNetworkOwner(nil)
			end
		end
	end
	]]
	--Char.Humanoid.PlatformStand = true
	--Char.Humanoid:ChangeState(Enum.HumanoidStateType.Dead)
	--Char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.)
	--[[
	Char.Ragdoll.Health = 0
	Char.Ragdoll:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
	Char.Ragdoll:ChangeState(Enum.HumanoidStateType.Ragdoll)
	]]
	h2:ChangeState(Enum.HumanoidStateType.Dead)
	if gvelo.Magnitude > 1 then
		Char.Torso:ApplyImpulse(gvelo * Vector3.new(100, 0, 100))
	else
		print("not using gvelo")
		Char.Torso:ApplyImpulse(Char.Torso.CFrame.LookVector * -(Vector3.new(100, 0, 100).Magnitude))
	end
	

	--Char.Humanoid.PlatformStand = true
	--[[
	coroutine.resume(coroutine.create(function()
		while Char.Parent and Char:FindFirstChild("Ragdoll") do
			Char.Ragdoll.Health = 1
			Char.Ragdoll:ChangeState(Enum.HumanoidStateType.Dead)
			wait()
			if not Char:FindFirstChild("Ragdoll") then
				return
			end
			Char.Ragdoll.Health = 0
			wait()
		end
	end))
	]]
	pnil(plr)
end

Any help would by appreciated :slight_smile:

Im having the same issue with the ragdoll staying alive

This is a really annoying issue that happens with a lot of ragdoll modules. The humanoid just doesn’t want to die, which is annoying. I’ve tried to figure it out before, but the best solution I found was to quickly set the Head’s parent to nil, then set it back to whatever it was.

Again, this probably isn’t the best solution, it’s just what worked for me.

Example:

local Head = --Replace this with the head
local oldParent = Head.Parent 

Head.Parent = nil 
task.defer(function() 
    task.wait()
-- Even more annoying, the time between deferring the function and it running
-- Isn't enough for it to kill the humanoid, so I had to put the task.wait()
    Head.Parent = oldParent 
end)
2 Likes

Hello !
Thanks, for your answer. I’m actually observing the behavior.
I will mark as answer if I no longer observe the bug.

It didn’t worked. But I suspect it’s because the Humanoid is already considered dead. So I modified the code a bit to set humanoid’s health 100 before removing the head and replacing it. Still observing behaviour.

Hey,
Your solution works !
I just had to modify it a bit.
Here is the working code:

RagDollFunc.OnInvoke = function(plr)
	plr.TeamColor = BrickColor.new("Institutional white")
	if not isAllowed(plr) then
		return
	end
	if plr.Character == nil then
		return
	end
	plr.Character.Archivable = true
	local Char = plr.Character:Clone()
	plr.Character.Archivable = false
	plr.Character.Parent = nil
	--Char.Humanoid.Health = 100
	--Char.Humanoid:ChangeState(Enum.HumanoidStateType.Running)
	if Char:FindFirstChild("CrouchValue") then
		Char:FindFirstChild("CrouchValue"):Destroy()
	end
	if Char:FindFirstChild("Fax") then
		Char:FindFirstChild("Fax"):Destroy()
	end
	if Char:FindFirstChild("C4Back") then
		Char:FindFirstChild("C4Back"):Destroy()
	end
	for i,v in pairs(Char.Humanoid:FindFirstChildWhichIsA("Animator"):GetPlayingAnimationTracks()) do
		v:Stop()
		v:Destroy()
	end
	local h2 = Instance.new("Humanoid")
	h2.Name = "Ragdoll"
	h2.NameOcclusion = Enum.NameOcclusion.NoOcclusion
	h2.BreakJointsOnDeath = false
	Char.Humanoid:Destroy()
	local gvelo = Char.Torso.AssemblyLinearVelocity
	for _, v in pairs(Char:GetDescendants()) do
		if v:IsA("Motor6D") then
			local Att0, Att1 = Instance.new("Attachment"), Instance.new("Attachment")
			Att0.CFrame = v.C0
			Att1.CFrame = v.C1
			Att0.Parent = v.Part0
			Att1.Parent = v.Part1
			local BSC = Instance.new("BallSocketConstraint")
			BSC.LimitsEnabled = true
			BSC.TwistLimitsEnabled = true
			BSC.TwistLowerAngle = -20
			BSC.TwistUpperAngle = 20
			BSC.Attachment0 = Att0
			BSC.Attachment1 = Att1
			BSC.Name = v.Name
			BSC.Parent = v.Part0

			v:Destroy()
		end
	end
	for _, v in pairs(Char:GetDescendants()) do
		if v:IsA("BaseScript") then
			v:Destroy()
		end
	end
	h2.Parent = Char
	game["Run Service"].Heartbeat:Wait()
	Char.Parent = workspace.Debris
	--[[
	for _, v in pairs(Char:GetDescendants()) do
		if v:IsA("BasePart") then
			if v:CanSetNetworkOwnership() then
				v:SetNetworkOwner(nil)
			end
		end
	end
	]]
	--Char.Humanoid.PlatformStand = true
	--Char.Humanoid:ChangeState(Enum.HumanoidStateType.Dead)
	--Char.Humanoid:SetStateEnabled(Enum.HumanoidStateType.)
	--[[
	Char.Ragdoll.Health = 0
	Char.Ragdoll:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
	Char.Ragdoll:ChangeState(Enum.HumanoidStateType.Ragdoll)
	]]
	for i = 1, 5 do
		game["Run Service"].Heartbeat:Wait()
	end
	
	-- Thanks to Inconcludable for providing the code.
	local Head = Char:FindFirstChild("Head")
	local oldParent = Head.Parent 

	Head.Parent = nil 
	
	for i = 1, 5 do
		game["Run Service"].Heartbeat:Wait()
	end
	-- Even more annoying, the time between deferring the function and it running
	-- Isn't enough for it to kill the humanoid, so I had to put the task.wait()
	Head.Parent = oldParent 
	
	-- Fix code end
	
	if gvelo.Magnitude > 1 then
		Char.Torso:ApplyImpulse(gvelo * Vector3.new(100, 0, 100))
	else
		print("not using gvelo")
		Char.Torso:ApplyImpulse(Char.Torso.CFrame.LookVector * -(Vector3.new(100, 0, 100).Magnitude))
	end
	

	--Char.Humanoid.PlatformStand = true
	--[[
	coroutine.resume(coroutine.create(function()
		while Char.Parent and Char:FindFirstChild("Ragdoll") do
			Char.Ragdoll.Health = 1
			Char.Ragdoll:ChangeState(Enum.HumanoidStateType.Dead)
			wait()
			if not Char:FindFirstChild("Ragdoll") then
				return
			end
			Char.Ragdoll.Health = 0
			wait()
		end
	end))
	]]
	if plr.Character then
		plr.Character:Destroy()
		plr.Character = nil
	end
end

Thanks you.

After some investigations, the floating ragdolls was caused by Network Ownership going crazy, letting client simulates a floating ragdoll, the solution is to set the ownership of each parts to the server.