Current Version
Version 1.6.9
Newest change:
· performance improvements // 21.02.2026 (Version 1.6.9)
-> increased performance by not always creating new instances at ragdoll (currently just for 'Stable')
-> changed some code styling
INTRODUCTION
Hey Devforum, so I just made another Ragdoll System, I know there are like quadrillion other ones to use out there, but I still decided to make my own. I am being honest, I can’t really say why you should use this over other ones but
- I am using this for myself, so it will receive continued support
- It is easy to use
- It has some easy to configure settings
DISCLAIMER
Keep in mind, I am definitely not the best scripter, so some code may not be very good.
SCRIPTS (Version 1.6.8)
R6RagdollServer
--[[ System By @Liam
-> Version 1.6.8
♥ Thanks for using this!! ♥
--]]
--||Services||--
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
--||Ragdoll CFrames (can be changed)||--
local attachmentCFrames = {
--HEAD
["Neck"] = {CFrame.new(0, 1, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1), CFrame.new(0, -0.5, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1)},
--ARMS
["Left Shoulder"] = {CFrame.new(-1.3, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1), CFrame.new(0.2, 0.75, 0, -1, 0, 0, 0, -1, 0, 0, 0, 1)},
["Right Shoulder"] = {CFrame.new(1.3, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1), CFrame.new(-0.2, 0.75, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)},
--LEGS
["Left Hip"] = {CFrame.new(-0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
["Right Hip"] = {CFrame.new(0.5, -1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1), CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)},
}
--||Don't change this||--
local ragdollInstanceNames = {
RagdollAttachment = true,
RagdollConstraint = true,
ColliderPart = true,
}
--||Settings||--
local ragdoll = {
ragdollSounds = true, --if you wanna have ragdoll sounds when the body hits something set this to true
ragdollOnDeath = true, --if you want to automatically enable ragdoll on death
ragdollOnGameStart = true, --if you want every character that can be found in workspace at the start of the game to use this ragdoll system
}
local constrainsAndWelds = {
LimitBSC = true, --if you want to have a rotation limit for the BallSocketConstraint
}
local fixes = {
VoidBug = true, --fixes the bug that the player doesnt respawn when they fall into the void
}
local npcSettings = {
fixNpcFling = true, --fixes the npc flinging away when they get up (this sets the enemies hrp networkownership to nil)
npcFolders = {}, --if you have specific npc folders add them in the table, example: npcFolders = {workspace.Enemies, workspace.Enemies2}
}
------------------------------------------------------------------------------------------------------------------
--//
local function createImpactSound(parent, soundScript)
local sound = soundScript:Clone()
sound.Parent = parent
sound.Disabled = false
end
--//playing a sound when those body parts hit something
local function PlayRagdollSounds(char)
createImpactSound(char.Head, script.ImpactSound)
createImpactSound(char["Left Arm"], script.ImpactSound)
createImpactSound(char["Right Arm"], script.ImpactSound)
end
--//checking if a model is a valid Character
local function isCharacterModel(model)
return model:IsA("Model") and model:FindFirstChildWhichIsA("Humanoid")
end
--//creating the parts that are gonna be colliding with the world
local function createColliderPart(part)
if not part then return end
local rp = Instance.new("Part")
rp.Name = "ColliderPart"
rp.Size = part.Size / 1.7
rp.Massless = true
rp.CFrame = part.CFrame
rp.Transparency = 1
local wc = Instance.new("WeldConstraint")
wc.Part0 = rp
wc.Part1 = part
wc.Parent = rp
rp.Parent = part
end
--//replacing the joints and other stuff
local function replaceJoints(char, hum)
local hrp = char:FindFirstChild("HumanoidRootPart")
hum.PlatformStand = true
hum.AutoRotate = false
if not hrp then return end
hrp.Massless = true
hrp.CanCollide = false
for _, motor in char:GetDescendants() do
if motor:IsA("Motor6D") and attachmentCFrames[motor.Name] then
motor.Enabled = false
local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
a0.CFrame = attachmentCFrames[motor.Name][1]
a1.CFrame = attachmentCFrames[motor.Name][2]
a0.Name = "RagdollAttachment"
a1.Name = "RagdollAttachment"
createColliderPart(motor.Part1)
local b = Instance.new("BallSocketConstraint")
b.Attachment0 = a0
b.Attachment1 = a1
b.Name = "RagdollConstraint"
b.Radius = 0.15
b.LimitsEnabled = constrainsAndWelds.LimitBSC
b.TwistLimitsEnabled = motor.Name == "Neck"
b.MaxFrictionTorque = 0
b.Restitution = 0
b.UpperAngle = motor.Name == "Neck" and 45 or 90
b.TwistLowerAngle = motor.Name == "Neck" and -70 or -45
b.TwistUpperAngle = motor.Name == "Neck" and 70 or 45
a0.Parent = motor.Part0
a1.Parent = motor.Part1
b.Parent = motor.Parent
end
end
if ragdoll.ragdollSounds then PlayRagdollSounds(char) end
end
--//resetting the joints and all the other properties
local function resetJoints(hum)
local char = hum.Parent
local hrp = char.HumanoidRootPart
char:SetAttribute("IsRagdoll", false)
hum.PlatformStand = false
hum.AutoRotate = true
hrp.Massless = false
hrp.CanCollide = true
if ragdoll.ragdollSounds then
for _, Script in char:GetDescendants() do
if Script:IsA("Script") and Script.Name == "ImpactSound" then
Script:Destroy()
end
end
end
if hum.Health <= 0 then return end --we don't want the player to stand up again if they are dead
for _, part in char:GetDescendants() do
if part:IsA("BasePart") then
part.AssemblyLinearVelocity = Vector3.zero
part.AssemblyAngularVelocity = Vector3.zero
end
end
for _, instance in char:GetDescendants() do
if ragdollInstanceNames[instance.Name] then
instance:Destroy()
end
if instance:IsA("Motor6D") then
instance.Enabled = true
end
end
hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
hum:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
hum:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
local isPlayer = Players:GetPlayerFromCharacter(hum.Parent)
if not isPlayer and npcSettings["fixNpcFling"] == true then
hrp:SetNetworkOwner(nil)
local float = Instance.new("BodyPosition")
float.Position = hrp.Position + vector.create(0, 2, 0)
float.MaxForce = Vector3.new(1e5, 1e5, 1e5)
float.P = 1e4
float.Parent = hrp
Debris:AddItem(float, 0.25)
local stabilizer = Instance.new("BodyGyro")
stabilizer.P = 1e6
stabilizer.D = 500
stabilizer.MaxTorque = vector.create(1e4, 0, 1e4)
stabilizer.Parent = hrp
Debris:AddItem(stabilizer, .25)
end
end
--//applying the ragdoll
local function applyRagdollToCharacter(char) --
local hum = char:FindFirstChild("Humanoid")
local torso = char:FindFirstChild("Torso")
if hum and torso then
hum.BreakJointsOnDeath = not ragdoll.ragdollOnDeath
hum.RequiresNeck = not ragdoll.ragdollOnDeath
char:SetAttribute("IsRagdoll", false) --setting ragdoll to false from the beginning on
char:GetAttributeChangedSignal("IsRagdoll"):Connect(function()
if char:GetAttribute("IsRagdoll") then
replaceJoints(char, hum)
else
resetJoints(hum)
end
end)
hum.Died:Once(function() --on death
if not ragdoll.ragdollOnDeath then return end
char:SetAttribute("IsRagdoll", true)
torso:ApplyImpulse(torso.CFrame.LookVector * 100)
end)
end
end
--//
local function applyRagdollToAllCharacters()
for _, char in workspace:GetDescendants() do
if isCharacterModel(char) then
applyRagdollToCharacter(char)
end
end
end
if ragdoll.ragdollOnGameStart then applyRagdollToAllCharacters() end
--//applying the ragdoll to the specific npc folders
for _, folder in npcSettings.npcFolders do
for _, char in folder:GetChildren() do
applyRagdollToCharacter(char)
end
folder.ChildAdded:Connect(function(child)
if isCharacterModel(child) then
applyRagdollToCharacter(child)
end
end)
end
--//
Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
applyRagdollToCharacter(char)
if fixes.VoidBug then
char.ChildRemoved:Connect(function() --this fixes the void bug
if char.WorldPivot.Position.Y <= workspace.FallenPartsDestroyHeight then
char.Humanoid.Health = 0 --so that the player just dies normaly when they fall into the void
end
end)
end
end)
end)
R15RagdollServer
--[[ System By @Liam
-> Version 1.6.8
♥ Thanks for using this!! ♥
--]]
--||Services||--
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
--||Ragdoll CFrames (can be changed)||--
local attachmentCFrames = {
--HEAD
["Neck"] = {CFrame.new(0, .75, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1), CFrame.new(0, -0.5, 0, 0, -1, 0, 1, 0, -0, 0, 0, 1)},
--ARMS
["LeftShoulder"] = {CFrame.new(-.75, 0.75, 0), CFrame.new(0, 0.75, 0)},
["RightShoulder"] = {CFrame.new(.75, 0.75, 0), CFrame.new(-0, 0.75, 0)},
--
["LeftElbow"] = {CFrame.new(-0, 0, 0), CFrame.new(0, 0.6, 0)},
["RightElbow"] = {CFrame.new(0, 0, 0), CFrame.new(-0, 0.6, 0)},
--
["LeftWrist"] = {CFrame.new(-0, 0, 0), CFrame.new(0, .6, 0)},
["RightWrist"] = {CFrame.new(0, 0, 0), CFrame.new(-0, .6, 0)},
--LEGS
["LeftHip"] = {CFrame.new(-0.5, -0, 0), CFrame.new(0, .75, 0)},
["RightHip"] = {CFrame.new(0.5, -0, 0), CFrame.new(0, .75, 0)},
--
["LeftKnee"] = {CFrame.new(-0, -0, 0), CFrame.new(0, .6, 0)},
["RightKnee"] = {CFrame.new(0, -0, 0), CFrame.new(0, .6, 0)},
--
["LeftAnkle"] = {CFrame.new(-0, -0, 0), CFrame.new(0, .6, 0)},
["RightAnkle"] = {CFrame.new(0, -0, 0), CFrame.new(0, .6, 0)},
--TORSO
["Root"] = {CFrame.new(0, 0, 0), CFrame.new(0, 0, 0)},
--["Waist"] = {CFrame.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), CFrame.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)},
}
--||Don't change this||--
local ragdollInstanceNames = {
RagdollAttachment = true,
RagdollConstraint = true,
ColliderPart = true,
}
--||Settings||--
local ragdoll = {
ragdollSounds = true, --if you wanna have ragdoll sounds when the body hits something set this to true
ragdollOnDeath = true, --if you want to automatically enable ragdoll on death
ragdollOnGameStart = true, --if you want every character that can be found in workspace at the start of the game to use this ragdoll system
}
local constrainsAndWelds = {
LimitBSC = true, --if you want to have a rotation limit for the BallSocketConstraint
}
local fixes = {
VoidBug = true, --fixes the bug that the player doesnt respawn when they fall into the void
}
local npcSettings = {
fixNpcFling = true, --fixes the npc flinging away when they get up (this sets the enemies hrp networkownership to nil)
npcFolders = {}, --if you have specific npc folders add them in the table, example: npcFolders = {workspace.Enemies, workspace.Enemies2}
}
------------------------------------------------------------------------------------------------------------------
--//
local function createImpactSound(parent, soundScript)
local sound = soundScript:Clone()
sound.Parent = parent
sound.Disabled = false
end
--//playing a sound when those body parts hit something
local function PlayRagdollSounds(char)
createImpactSound(char.Head, script.ImpactSound)
createImpactSound(char.LeftLowerArm, script.ImpactSound)
createImpactSound(char.RightLowerArm, script.ImpactSound)
end
--//checking if a model is a valid Character
local function isCharacterModel(model)
return model:IsA("Model") and model:FindFirstChildWhichIsA("Humanoid")
end
--//creating the parts that are gonna be colliding with the world
local function createColliderPart(part)
if not part then return end
local rp = Instance.new("Part")
rp.Name = "ColliderPart"
rp.Size = part.Size / 1.7
rp.Massless = true
rp.CFrame = part.CFrame
rp.Transparency = 1
local wc = Instance.new("WeldConstraint")
wc.Part0 = rp
wc.Part1 = part
wc.Parent = rp
rp.Parent = part
end
--//replacing the joints and other stuff
local function replaceJoints(char, hum)
local hrp = char:FindFirstChild("HumanoidRootPart")
hum.PlatformStand = true
hum.AutoRotate = false
if not hrp then return end
hrp.Massless = true
hrp.CanCollide = false
for _, motor in char:GetDescendants() do
if motor:IsA("Motor6D") and attachmentCFrames[motor.Name] then
motor.Enabled = false
local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
a0.CFrame = attachmentCFrames[motor.Name][1]
a1.CFrame = attachmentCFrames[motor.Name][2]
a0.Name = "RagdollAttachment"
a1.Name = "RagdollAttachment"
createColliderPart(motor.Part1)
local b = Instance.new("BallSocketConstraint")
b.Attachment0 = a0
b.Attachment1 = a1
b.Name = "RagdollConstraint"
b.Radius = 0.15
b.LimitsEnabled = constrainsAndWelds.LimitBSC
b.TwistLimitsEnabled = motor.Name == "Neck"
b.MaxFrictionTorque = 0
b.Restitution = 0
b.UpperAngle = motor.Name == "Neck" and 45 or 90
b.TwistLowerAngle = motor.Name == "Neck" and -70 or -45
b.TwistUpperAngle = motor.Name == "Neck" and 70 or 45
a0.Parent = motor.Part0
a1.Parent = motor.Part1
b.Parent = motor.Parent
end
end
if ragdoll.ragdollSounds then PlayRagdollSounds(char) end
end
--//resetting the joints and all the other properties
local function resetJoints(hum)
local char = hum.Parent
local hrp = char.HumanoidRootPart
char:SetAttribute("IsRagdoll", false)
hum.PlatformStand = false
hum.AutoRotate = true
hrp.Massless = false
hrp.CanCollide = true
if ragdoll.ragdollSounds then
for _, Script in char:GetDescendants() do
if Script:IsA("Script") and Script.Name == "ImpactSound" then
Script:Destroy()
end
end
end
if hum.Health <= 0 then return end --we don't want the player to stand up again if they are dead
for _, part in char:GetDescendants() do
if part:IsA("BasePart") then
part.AssemblyLinearVelocity = Vector3.zero
part.AssemblyAngularVelocity = Vector3.zero
end
end
for _, instance in char:GetDescendants() do
if ragdollInstanceNames[instance.Name] then
instance:Destroy()
end
if instance:IsA("Motor6D") then
instance.Enabled = true
end
end
hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
hum:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
hum:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
local isPlayer = Players:GetPlayerFromCharacter(hum.Parent)
if not isPlayer and npcSettings["fixNpcFling"] == true then
hrp:SetNetworkOwner(nil)
local float = Instance.new("BodyPosition")
float.Position = hrp.Position + vector.create(0, 2, 0)
float.MaxForce = Vector3.new(1e5, 1e5, 1e5)
float.P = 1e4
float.Parent = hrp
Debris:AddItem(float, 0.25)
local stabilizer = Instance.new("BodyGyro")
stabilizer.P = 1e6
stabilizer.D = 500
stabilizer.MaxTorque = vector.create(1e4, 0, 1e4)
stabilizer.Parent = hrp
Debris:AddItem(stabilizer, .25)
end
end
--//applying the ragdoll
local function applyRagdollToCharacter(char)
local hum = char:FindFirstChild("Humanoid")
local upperTorso = char:FindFirstChild("UpperTorso")
if hum and upperTorso then
hum.BreakJointsOnDeath = not ragdoll.ragdollOnDeath
hum.RequiresNeck = not ragdoll.ragdollOnDeath
char:SetAttribute("IsRagdoll", false) --setting ragdoll to false from the beginning on
char:GetAttributeChangedSignal("IsRagdoll"):Connect(function()
if char:GetAttribute("IsRagdoll") then
replaceJoints(char, hum)
else
resetJoints(hum)
end
end)
hum.Died:Once(function() --on death
if not ragdoll.ragdollOnDeath then return end
char:SetAttribute("IsRagdoll", true)
upperTorso:ApplyImpulse(upperTorso.CFrame.LookVector * 100)
end)
end
end
--//
local function applyRagdollToAllCharacters()
for _, char in workspace:GetDescendants() do
if isCharacterModel(char) then
applyRagdollToCharacter(char)
end
end
end
if ragdoll.ragdollOnGameStart then applyRagdollToAllCharacters() end
--//applying the ragdoll to the specific npc folders
for _, folder in npcSettings.npcFolders do
for _, char in folder:GetChildren() do
applyRagdollToCharacter(char)
end
folder.ChildAdded:Connect(function(child)
if isCharacterModel(child) then
applyRagdollToCharacter(child)
end
end)
end
--//
Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
applyRagdollToCharacter(char)
if fixes.VoidBug then
char.ChildRemoved:Connect(function() --this fixes the void bug
if char.WorldPivot.Position.Y <= workspace.FallenPartsDestroyHeight then
char.Humanoid.Health = 0 --so that the player just dies normaly when they fall into the void
end
end)
end
end)
end)
RagdollClient
--[[ System By @Liam
-> Version 1.6.8
♥ Thanks for using this!! ♥
--]]
--||Services||--
local Players = game:GetService("Players")
--||Character||--
local plr = Players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")
local torso = char:FindFirstChild("Torso") or char:FindFirstChild("UpperTorso")
print("This game uses 'Liam's Ragdoll System' V 1.6.8!") -- please leave this in as a support!
------------------------------------------------------------------------------------------------------------------
--//when the player gets ragdolled / unRagdolled
char:GetAttributeChangedSignal("IsRagdoll"):Connect(function()
local isRagdoll = char:GetAttribute("IsRagdoll")
if isRagdoll and torso then
hum:ChangeState(Enum.HumanoidStateType.Ragdoll)
hum:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
torso:ApplyImpulse(torso.CFrame.LookVector * 75) --push!
else
hum:ChangeState(Enum.HumanoidStateType.GettingUp)
end
end)
--//this happens when the player dies
hum.Died:Connect(function()
hum.Health = 0
if not torso then return end
torso:ApplyImpulse(torso.CFrame.LookVector * 100)
end)
THE MODEL
https://create.roblox.com/store/asset/140489636987227/Liams-Ragdoll-System
HOW TO USE (KINDA NOT SO UP TO DATE)
END
Not much more to say, have a nice day. If you find bugs, tell me and I will try to fix them!
Random Pic Here
Cute cat here:
[spoiler]

[/spoiler]
Credits
Credits for the Original Script made by @CompletedLoop
[DEPRECATED] Perfect R6 Ragdoll - Easiest Ragdoll System for R6 Avatars
