Ragdoll doesn't attach head

I am attempting to use a ragdoll module created by @kalabgs. I have a script set up to automatically rig the player’s character when the character is added, and for the most part this works fine. The only thing is that it refuses to create the Attachment and BallSocketConstraint for the Neck Motor6D. This causes the head to pop off when the character is ragdolled, which kills them, and I need them to stay alive when they ragdoll for specific parts of my game.

If I add a wait for around 5 seconds it creates the Attachment, but not the constraint. If I add a wait for around 10 seconds, both are created and it works fine. This would be fine if it wasn’t for the fact that I need the ragdoll directly after spawning in. Below is the ragdoll module:

local mod = {}

function mod:RigPlayer(Character : Model)
	local hum : Humanoid? = Character:WaitForChild("Humanoid")
	local hrp : BasePart? = Character:WaitForChild("HumanoidRootPart")

	assert(hum,Character.Name.." isnt a humanoid")

	hum.BreakJointsOnDeath = false
	local WeldConstranint = Instance.new("WeldConstraint")
	WeldConstranint.Parent = hrp
	for _,v in pairs(Character:GetDescendants()) do
		if v:IsA("Motor6D") then
			local BallSocket = Instance.new("BallSocketConstraint")
			BallSocket.Parent = v.Part0
			BallSocket.Name = "BC"
			print("Processing part: " .. v.Name, "Part0: " .. v.Part0.Name, "Part1: " .. v.Part1.Name)
			if v.Part1 ~= Character.PrimaryPart and v.Part0 ~= Character.PrimaryPart then
				v.Part1.CanCollide = false
				v.Part0.CanCollide = false
			end

			local att1 = Instance.new("Attachment")
			local att2 = Instance.new("Attachment")
			att1.Parent = v.Part0
			att2.Parent = v.Part1
			att1.Name = "AttRag"
			att2.Name = "AttRag"
			att2.Position = v.C1.Position
			att1.WorldPosition= att2.WorldPosition

			BallSocket.LimitsEnabled = true
			BallSocket.TwistLimitsEnabled = true

			BallSocket.Attachment0 = att1
			BallSocket.Attachment1 = att2

			if v.Part0 == Character.PrimaryPart and v.Part1 ~= Character.PrimaryPart then
				WeldConstranint.Part0 = Character.PrimaryPart
				WeldConstranint.Part1 = v.Part1
				WeldConstranint.Enabled = false
			end
		end
	end
end

function mod:Ragdoll(Character : Model)
	local humanoid : Humanoid = Character:WaitForChild("Humanoid")
	for _, v in ipairs(Character:GetDescendants()) do
		if v:IsA("Motor6D") then
			if v.Part1 ~= Character.PrimaryPart and v.Part0 ~= Character.PrimaryPart then
				v.Part1.CanCollide = true
				v.Enabled = false
			else
				Character.PrimaryPart:FindFirstChild("WeldConstraint").Enabled = true
				Character.PrimaryPart.CanCollide = false
			end
		end
	end
end

function mod:Recover(Character : Model)
	local humanoid : Humanoid = Character:WaitForChild("Humanoid")
	for _, v in ipairs(Character:GetDescendants()) do
		if v:IsA("Motor6D") then
			if v.Part1 ~= Character.PrimaryPart and v.Part0 ~= Character.PrimaryPart then
				v.Part1.CanCollide = false
				v.Enabled = true
			else
				Character.PrimaryPart:FindFirstChild("WeldConstraint").Enabled = false
				Character.PrimaryPart.CanCollide = true
			end
		end
	end
end

function mod:Deathphysics(Character : Model)
	for _, v in ipairs(Character:GetDescendants()) do
		if v:IsA("Motor6D") then
			if v.Part1 ~= Character.PrimaryPart and v.Part0 ~= Character.PrimaryPart then
				v.Part1.CanCollide = true
				v:Destroy()
			else
				Character.PrimaryPart:FindFirstChild("WeldConstraint").Enabled = true
				Character.PrimaryPart.CanCollide = false
			end
		end
	end
end

return mod

And this is the script I created (omitting what isn’t needed):

function CharacterService:KnitStart()
    local Ragdoll = require(script.Parent.Parent.Ragdoll)

    function CharacterService:RigPlayer(Player: Player)
        local Character = Player.Character or Player.CharacterAdded:Wait()
        Ragdoll:RigPlayer(Character)
    end
    
    function CharacterService:UpdateCharacterInfo(Player: Player)
        CharacterService:RigPlayer(Player)
        
        Humanoid.StateChanged:Connect(function(_, NewState: Enum.HumanoidStateType)
            if NewState == Enum.HumanoidStateType.Ragdoll then
                CharacterService:Ragdoll(Player)
            end
        end)
    end
    
    local function PlayerAdded(Player: Player)
        CharacterService:UpdateCharacterInfo(Player)
        Player.CharacterAdded:Connect(function()
            CharacterService:UpdateCharacterInfo(Player)
        end)
    end

    Players.PlayerAdded:Connect(PlayerAdded)
    for _, Player in pairs(Players:GetPlayers()) do
        PlayerAdded(Player)
    end
end

There are also no errors that are outputted. Any help would be appreciated!

2 Likes

Have you tried waiting for CharacterAppearanceLoaded?

Code:

function CharacterService:KnitStart()
	local Ragdoll = require(script.Parent.Parent.Ragdoll)

	function CharacterService:RigPlayer(Player: Player)
		local Character = Player.Character or Player.CharacterAppearanceLoaded:Wait()
		Ragdoll:RigPlayer(Character)
	end

	function CharacterService:UpdateCharacterInfo(Player: Player)
		CharacterService:RigPlayer(Player)

		Humanoid.StateChanged:Connect(function(_, NewState: Enum.HumanoidStateType)
			if NewState == Enum.HumanoidStateType.Ragdoll then
				CharacterService:Ragdoll(Player)
			end
		end)
	end

	local function PlayerAdded(Player: Player)
		CharacterService:UpdateCharacterInfo(Player)
		Player.CharacterAppearanceLoaded:Connect(function()
			CharacterService:UpdateCharacterInfo(Player)
		end)
	end

	Players.PlayerAdded:Connect(PlayerAdded)
	for _, Player in Players:GetPlayers() do
		PlayerAdded(Player)
	end
end
2 Likes

Are you testing this immediately after starting test mode in Studio?
I think the physics engine is one of the last things to load. I’ve noticed it with things like swinging doors and other Constraints when testing.
Try test mode, but wait for 20 or 30 seconds before running the script to see if that makes a difference.

1 Like

Part of the ragdoll is connected to when the Humanoid dies, so I’ve tested it numerous times after 20 or 30 seconds have already passed. As I stated before the issue isn’t that the Constraints themselves aren’t working, but they aren’t being created specifically for the Neck/Head.

1 Like

Unfortunately, it didn’t seem to work for me.

2 Likes

Create the parts that aren’t working in an independent script and figure out why it works there and not in the loop.

2 Likes