How can I make my ragdoll smoother?

Right now, I’m just looping through all of the motor6d’s inside of the character and replacing them with ballsocketconstraints. I have also copied a bunch of twist angles and upper angles from a working source.

Inside the model, they also have hinge constraints and collision constraints. What are the purposes of hinge and collision constraints in a ragdoll?

This is my code right now

local Players = game:GetService("Players")
Players.CharacterAutoLoads = false

--local Player = Players.LocalPlayer
local Player = script.Parent.Parent
local Char = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Char:WaitForChild("Humanoid")
Humanoid.BreakJointsOnDeath = false


local constraints = {
	["LeftAnkle"] = {Limits = true, Twist = true, UpperAngle = 30,LowerAngle = nil, TwistLowerAngle = -45, TwistUpperAngle = 30}; 
	["RightAnkle"] = {Limits = true, Twist = true, UpperAngle = 30,LowerAngle = nil, TwistLowerAngle = -45, TwistUpperAngle = 30}; 

	["LeftElbow"] = {Limits = true, Twist = false, UpperAngle = 135,LowerAngle = nil, TwistLowerAngle = nil, TwistUpperAngle = nil}; 
	["RightElbow"] = {Limits = true, Twist = false, UpperAngle = 135,LowerAngle = nil, TwistLowerAngle = nil, TwistUpperAngle = nil}; 

	
	["LeftHip"] = {Limits = true, Twist = true, UpperAngle = 50,LowerAngle = nil, TwistLowerAngle = 100, TwistUpperAngle = -45};
	["RightHip"] = {Limits = true, Twist = true, UpperAngle = 50,LowerAngle = nil, TwistLowerAngle = 100, TwistUpperAngle = -45};
	
	["LeftKnee"] = {Limits = true, Twist = false, UpperAngle = 0,LowerAngle = -140, TwistLowerAngle = nil, TwistUpperAngle = nil};-- 
	["RightKnee"] = {Limits = true, Twist = false, UpperAngle = 0,LowerAngle = -140, TwistLowerAngle = nil, TwistUpperAngle = nil};-- 

	
	["Neck"] = {Limits = true, Twist = true, UpperAngle = 60,LowerAngle = nil, TwistLowerAngle = -75, TwistUpperAngle = 60};
	
	
	["LeftShoulder"] = {Limits = true, Twist = true, UpperAngle = 45,LowerAngle = nil, TwistLowerAngle = -90, TwistUpperAngle = 150};-- 
	["RightShoulder"] = {Limits = true, Twist = true, UpperAngle = 45,LowerAngle = nil, TwistLowerAngle = -90, TwistUpperAngle = 150};-- 

	
	["Waist"] = {Limits = true, Twist = true, UpperAngle = 30,LowerAngle = nil, TwistLowerAngle = -55, TwistUpperAngle = 25};
	
	["LeftWrist"] = {Limits = true, Twist = true, UpperAngle = 30,LowerAngle = nil, TwistLowerAngle = -45, TwistUpperAngle = 45};
	["RightWrist"] = {Limits = true, Twist = true, UpperAngle = 30,LowerAngle = nil, TwistLowerAngle = -45, TwistUpperAngle = 45};

}

Humanoid.Died:Connect(function()
	print("hm?")
	for index, v in pairs(Char:GetDescendants()) do
		if v:IsA("Motor6D") then
			local ballSocketConstraint = Instance.new("BallSocketConstraint")

			local attachmentName = v.Parent:FindFirstChild(v.Name.."Attachment") or v.Parent:FindFirstChild(v.Name.."RigAttachment")
			local secondAttachmentName = v.Part0:FindFirstChild(v.Name.."Attachment") or v.Part0:FindFirstChild(v.Name.."RigAttachment")

			if attachmentName and secondAttachmentName then

				ballSocketConstraint.Parent = v.Parent
				ballSocketConstraint.Attachment0 = attachmentName
				ballSocketConstraint.Attachment1 = secondAttachmentName
				
				if v.Name ~= "Root" then
					print(v.Name)
					print(constraints[v.Name]["Limits"])
					ballSocketConstraint.LimitsEnabled = constraints[v.Name]["Limits"]
					ballSocketConstraint.TwistLimitsEnabled = constraints[v.Name]["Twist"]
					ballSocketConstraint.UpperAngle = constraints[v.Name]["UpperAngle"]
					ballSocketConstraint.TwistLowerAngle = constraints[v.Name]["TwistLowerAngle"]
					ballSocketConstraint.TwistUpperAngle = constraints[v.Name]["TwistUpperAngle"]
					
				end
				
				
				delay(1, function()
					v:Destroy()			

				end)
			end
		end
	end
end)

You should make constraints before the humanod dies and you can also use bindables to fire on your client to make it instanteous and fire on the server for others to see.

More Info:

So should I have a Humanoid.Died event on the client and then fire a remote on the server?