You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? I want to achieve the active ragdoll similar to the one in the video
-
What is the issue? I’m not sure how to make it as smooth and efficient, especially with the multiple animations playing with this
-
What solutions have you tried so far? Ive tried searching on the forum, not much information for me execpt for alittle bit of the IK and tweening for the active ragdolls, still kind of unsure how i could make one similar to the one in the video
so heres the video of the ragdoll im interested in trying to recreate, Roblox game development - RAGDOLL ALERT ![]()
![]()
- YouTube
and heres my progress with an active ragdoll right now
https://gyazo.com/2bbea384821c5461086e2afe8c3efbf6
--> Created June 6, 2023
--> Modified May 10, 2025
--> Make sure this script is located in StarterPlayer.StarterCharacterScripts
local Character: Model = script.Parent
local Torso: BasePart = Character:WaitForChild("Torso")
local Humanoid: Humanoid = Character:FindFirstChildOfClass("Humanoid")
--> Necessary for Ragdolling to function properly
Character.Humanoid.BreakJointsOnDeath = false
Character.Humanoid.RequiresNeck = true --> If your are having issues with your character randomly dying then set this to false
local ARM_MAX_LENGTH = 1
local ARM_MIN_LENGTH = 0.01
local LEG_MAX_LENGTH = 0.08
local LEG_MIN_LENGTH = 0.01
local HEAD_MAX_LENGTH = 0.01
local HEAD_MIN_LENGTH = 0.1
-- /////////////////////////////////////////////////////////////////////////////
-- Specific CFrame’s for the best looking “attachment” positions
local attachmentCFrames = {
["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)
},
["Left Shoulder"] = {
CFrame.new(-0.7, 0.6, -0.3, -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(0.5, 0.8, -0.3, 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)
},
["Left Hip"] = {
CFrame.new(-0.7, -1, -0.2, 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.2, -0.3, 0, 1, -0, -1, 0, 0, 0, 0, 1),
CFrame.new(0, 1, 0, 0, 1, -0, -1, 0, 0, 0, 0, 1)
},
}
-- We’ll track only these instance names for cleanup:
local ragdollInstanceNames = {
["RagdollAttachment"] = true,
["RagdollSpring"] = true,
["ColliderPart"] = true,
}
local Physics = game:GetService("PhysicsService")
Physics:RegisterCollisionGroup("ColliderPart")
-- BoolValue used to toggle ragdoll on/off
local RagdollValue = Instance.new("BoolValue")
RagdollValue.Name = "IsRagdoll"
RagdollValue.Parent = Character
local euphoriaValue = Instance.new("BoolValue")
euphoriaValue.Name = "Euphoria"
euphoriaValue.Parent = Character
-------------------------------------------------------------------------------------------------
-- Apply a small push to the torso when ragdoll begins
local function push()
Torso:ApplyImpulse(Torso.CFrame.LookVector * -100)
end
-- Create an invisible collider part inside each limb so ragdoll limbs collide properly
local function createColliderPart(part: BasePart)
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
Physics:SetPartCollisionGroup(rp,"ColliderPart")
local wc = Instance.new("WeldConstraint")
wc.Part0 = rp
wc.Part1 = part
wc.Parent = rp
rp.Parent = part
end
-- Replace all Motor6D joints with a SpringConstraint between attachments
function replaceJoints()
for _, motor: Motor6D in pairs(Character:GetDescendants()) do
if motor:IsA("Motor6D") and attachmentCFrames[motor.Name] then
motor.Enabled = false
-- Create the two ragdoll attachments
local a0 = Instance.new("Attachment")
local a1 = Instance.new("Attachment")
a0.CFrame = attachmentCFrames[motor.Name][1]
a1.CFrame = attachmentCFrames[motor.Name][2]
a0.Name = "RagdollAttachment"
a1.Name = "RagdollAttachment"
a0.Parent = motor.Part0
a1.Parent = motor.Part1
-- Invisible collider for proper physics collisions
createColliderPart(motor.Part1)
if motor.Name == "Neck" then
-- Use BallSocketConstraint on the neck
local bs = Instance.new("BallSocketConstraint")
bs.Attachment0 = a0
bs.Attachment1 = a1
bs.Name = "RagdollBallSocket"
-- Optional: enable limits if you want to cap head rotation
bs.LimitsEnabled = true
bs.UpperAngle = 45
bs.Parent = motor.Parent
else
-- Fallback to SpringConstraints on all other joints
local spring = Instance.new("SpringConstraint")
spring.Attachment0 = a0
spring.Attachment1 = a1
spring.Name = "RagdollSpring"
spring.Stiffness = 700
spring.Damping = 100
spring.Coils = 0
spring.MaxForce = 1000 -- tweak as needed
spring.LimitsEnabled = true
-- assign lengths per limb
if motor.Name == "Left Shoulder" or motor.Name == "Right Shoulder" then
spring.MaxLength = ARM_MAX_LENGTH
spring.MinLength = ARM_MIN_LENGTH
elseif motor.Name == "Left Hip" or motor.Name == "Right Hip" then
spring.MaxLength = LEG_MAX_LENGTH
spring.MinLength = LEG_MIN_LENGTH
else
-- any other Motor6D that slips through
spring.MaxLength = HEAD_MAX_LENGTH
spring.MinLength = HEAD_MIN_LENGTH
end
spring.Parent = motor.Parent
end
end
end
end
-- Removes all Ragdoll‐created instances and re‐enables the original Motor6D’s
function resetJoints()
if Humanoid.Health < 1 then
return
end
for _, instance in pairs(Character:GetDescendants()) do
if ragdollInstanceNames[instance.Name] then
instance:Destroy()
end
if instance:IsA("Motor6D") then
instance.Enabled = true
end
end
end
-- Toggles ragdoll on/off
function Ragdoll(value: boolean)
if value then
Humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
replaceJoints()
push()
value = true
task.wait(5)
else
resetJoints()
Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
value = false
end
end
function EnableEuphoria(value:boolean)
if value then
for _, Child in ipairs(game.Workspace["Rig-clone"].Aligner:GetDescendants()) do
if Child:IsA("AlignOrientation") or Child:IsA("AlignPosition") then
Child.Enabled = true
end
end
for _, Child in ipairs(game.Workspace["Rig-clone"].Springs:GetDescendants()) do
Child.Enabled = true
end
Ragdoll(true)
else
for _, Child in ipairs(game.Workspace["Rig-clone"].Aligner:GetDescendants()) do
if Child:IsA("AlignOrientation") and Child.Name ~= "Torso2" and Child.Name ~= "TorsoAlignPos" then
Child.Enabled = false
end
end
for _, Child in ipairs(game.Workspace["Rig-clone"].Springs:GetDescendants()) do
Child.Enabled = false
end
end
end
-------------------------------------------------------------------------------------------------
-- Connect the events
RagdollValue.Changed:Connect(Ragdoll)
euphoriaValue.Changed:Connect(EnableEuphoria)
Humanoid.Died:Once(function()
RagdollValue.Value = true
euphoriaValue.Value = true
end)
while true do
if euphoriaValue.Value == true then
local x = math.random(-1000,1000)
local z = math.random(-1000,1000)
script.Parent.Torso.SPIN.Torque = Vector3.new(x,0,z)
script.Parent.Torso.SPIN.Enabled = true
else
script.Parent.Torso.SPIN.Enabled = false
end
task.wait(1)
end
function Ragdoll(value: boolean)
if value then replaceJoints() else resetJoints() end
end
-------------------------------------------------------------------------------------------------
--> React when Ragdoll Attribute is changed
Character:GetAttributeChangedSignal("Ragdoll"):Connect(function()
Ragdoll(Character:GetAttribute("Ragdoll"))
end)
--> Ragdoll Character when the Humanoid dies
Humanoid.Died:Once(function()
Character:SetAttribute("Ragdoll", true)
end)
