Basic General Ragdoll Script R6 and R15

Hi all,
I’m here to share a ragdoll script I ended up with after improving a rudimentary ragdoll script. A user suggested I post the improved ragdoll script as a community resource because I ended up with something very useful, as apparently keeping hats on dead players while having persisting bodies is a tricky problem to solve.
It is a result of this post:
Ragdoll On Death Isn’t Working - Help and Feedback / Scripting Support - DevForum | Roblox
and the baseline code was written by StarJ3M

-Advantages over other typical ragdoll scripts:
Is compatible with both R6 and R15, though primarily with R15.
Makes use of network ownership to eliminate stuttering when the player transitions from alive to dead, even in high latency environments.
Keeps hats and clothing attached to the character.
Dead bodies persist after the player respawns.

-Limitations
Due to the way joints are made, R6 ragdolls tend to not have the best joints for them, and may look funny at times. If you care about this and/or your game uses primarily R6, you might want to find a script tailored to R6.
I also did not manually set Twist limits on most body parts, therefore they can twist to funny angles.

Heres the script. It can go anywhere scripts run, i.e. Workspace or ServerScriptService:
If you want bodies to despawn after a while, you can uncomment out line 7 and change the number to how long you want bodies to persist

game.Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Char)
		Char:WaitForChild("Humanoid").BreakJointsOnDeath = false
		Char.Humanoid.Died:Connect(function()
			local m = Instance.new("Model")
			m.Parent = game.Workspace
			--game:GetService("Debris"):AddItem(m,60)
			local g = Char:GetChildren()
			Char.HumanoidRootPart.CanCollide = false
			
		
			for _, v in pairs(Char:GetDescendants()) do
				if v.Parent == Char then
					v.Parent = m
				end
				if v:IsA("BasePart") then
					v:SetNetworkOwner(Player)
				end
				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.Attachment0 = Att0
					BSC.Attachment1 = Att1
					BSC.Parent = v.Part0
					if v.Part1.Name ==  "Head" then
						BSC.LimitsEnabled = true
						BSC.TwistLimitsEnabled = true
					end
					v.Enabled = false
				end
				if v.Name == "AccessoryWeld" then
					local WC = Instance.new("WeldConstraint")
					WC.Part0 = v.Part0
					WC.Part1 = v.Part1
					WC.Parent = v.Parent
					v.Enabled = false
				end
				if v.Name == "Head" and v:IsA("BasePart") then
					v.CanCollide = true
				end
			end
		end)
	end)
end)

Edit: Improved organization and fixed wrap targets being added in

58 Likes

Error I receive:

18:15:00.316 CanCollide is not a valid member of WrapTarget "Workspace.Model.Head.Head" - Server - RagdollDeath:41

Can be fixed by updating this line (40):

if v.Name == "Head" then
v.CanCollide = true
end

with:

if v.Name == "Head" and v.ClassName == not 'WrapTarget' then
v.CanCollide = true
end

Also your script produces this error:

Player:Move called, but player currently has no humanoid. (x362)

Which greatly decreases performance.

2 Likes

image

If this was made a year ago, and updated a year ago, why am I just now getting a notification about the post being linked??

10 Likes