I recently started working on a simple ragdoll script. The ragdoll works fine, but when I try to turn it off, the character starts flopping around. I noticed that if you hold jump before standing up, the character will not flop.
How does it work:
The server script firstly does quick setup for the ragdoll (hitboxes and constraints)
Every 5 seconds server script ragdolls or unragdolls the character by calling function ragdoll()
The ragdoll() function enables or disables the motors
The ragdoll() function forces character to jump if the Enable argument is false
The ragdoll() function sets the PlatformStand to true
The ragdoll() function sets character’s AutoRotate to false
The ragdoll() function sets the JumpPower to 0 to prevent jumping while in ragdoll.
Legacy script: (in the StarterPlayer.StarterCharacterScripts)
local char = script.Parent
char.Humanoid.BreakJointsOnDeath = false
char.Humanoid.RequiresNeck = false
char.Humanoid.UseJumpPower = true
local function createHitboxes(Include)
for i = 1, #char:GetChildren() do
local v = char:GetChildren()[i]
if v:IsA("MeshPart") and v:FindFirstChildWhichIsA("Motor6D") then
local hb = v:Clone()
hb:ClearAllChildren()
hb.Size = Vector3.new(0.6, 0.6, 0.6)
hb.CanCollide = true
hb.CollisionGroup = "Hitbox"
hb.Massless = true
hb.Transparency = 1
v.CanCollide = false
local weld = Instance.new("WeldConstraint")
weld.Part0 = v
weld.Part1 = hb
hb.Parent = v
weld.Parent = hb
elseif v.Name == "HumanoidRootPart" then
v.CollisionGroup = "Hitbox"
v.CanCollide = false
end
end
end
local function setupRagdoll()
for i = 1, #char:GetChildren() do
local v = char:GetChildren()[i]
if v:FindFirstChildWhichIsA("Motor6D") then
local motor = v:FindFirstChildWhichIsA("Motor6D")
local bis = Instance.new("BallSocketConstraint")
local at1 = Instance.new("Attachment")
local at2 = Instance.new("Attachment")
at1.Parent = motor.Part0
at1.CFrame = motor.C0
at2.Parent = motor.Part1
at2.CFrame = motor.C1
bis.Attachment0 = at1
bis.Attachment1 = at2
bis.LimitsEnabled = true
bis.Parent = motor.Parent
end
end
end
local function ragdoll(Enable)
for i = 1, #char:GetChildren() do
local v = char:GetChildren()[i]
if v:FindFirstChildWhichIsA("Motor6D") and v:FindFirstChildWhichIsA("Motor6D").Name ~= "Waist" and v:FindFirstChildWhichIsA("Motor6D").Name ~= "Root" then
v:FindFirstChildWhichIsA("Motor6D").Enabled = not Enable
end
end
char.Humanoid.EvaluateStateMachine = Enable
char.Humanoid.Jump = not Enable
char.Humanoid.PlatformStand = Enable
char.Humanoid.AutoRotate = not Enable
char.Humanoid.JumpPower = Enable and 0 or 50
char.Humanoid.EvaluateStateMachine = true
end
createHitboxes(true)
setupRagdoll()
while task.wait(5) do
ragdoll(not char.Humanoid.PlatformStand)
end
I found a somewhat solution to this, i was playing with EvaluateStateMachine, and eventually got a perfect get up, but the character was playing fall or walk animations while in-ragdoll, which really addected the way it looked. Still looking for a way to do it perfectly
The updated code if you want this:
local char = script.Parent
char.Humanoid.BreakJointsOnDeath = false
char.Humanoid.RequiresNeck = false
char.Humanoid.UseJumpPower = true
local function createHitboxes()
for i, v in pairs(char:GetChildren()) do
if v:IsA("MeshPart") and v:FindFirstChildWhichIsA("Motor6D") then
local hb = Instance.fromExisting(v)
hb.Size = Vector3.new(0.6, 0.6, 0.6)
hb.CanCollide = true
hb.CollisionGroup = "Hitbox"
hb.Massless = true
hb.Transparency = 1
hb.Name = "_R_Hitbox"
local weld = Instance.new("WeldConstraint")
weld.Part0 = v
weld.Part1 = hb
hb.Parent = v
weld.Parent = hb
elseif v.Name == "HumanoidRootPart" then
v.CollisionGroup = "Hitbox"
v.CanCollide = false
end
end
end
local function setupRagdoll()
for i, v in pairs(char:GetChildren()) do
local possm = v:FindFirstChildWhichIsA("Motor6D")
if possm then
local motor = possm
local bis = Instance.new("BallSocketConstraint")
local at1 = Instance.new("Attachment")
local at2 = Instance.new("Attachment")
at1.Parent = motor.Part0
at1.CFrame = motor.C0
at2.Parent = motor.Part1
at2.CFrame = motor.C1
bis.Attachment0 = at1
bis.Attachment1 = at2
bis.LimitsEnabled = true
bis.Parent = motor.Parent
end
end
end
local function disableAnimations(Enable:boolean)
for i, v in pairs(char.Animate:GetDescendants()) do
if v:IsA("Animation") then
v.Archivable = Enable
end
end
end
local function ragdoll(Enable:boolean)
disableAnimations(false)
char.Humanoid.AutoRotate = not Enable
task.wait(0.1)
char.HumanoidRootPart.Massless = false
char.Humanoid.AutoRotate = not Enable
for i, v in pairs(char:GetChildren()) do
char.Humanoid.Jump = true
local possm = v:FindFirstChildWhichIsA("Motor6D")
if possm and possm.Name ~= "Waist" and possm.Name ~= "Root" and possm.Name ~= "Neck" then
possm.Enabled = not Enable
v._R_Hitbox.CanCollide = Enable
v.CanCollide = false
elseif v.Name == "HumanoidRootPart" then
v.CanCollide = false
end
end
char.Humanoid.EvaluateStateMachine = false
if Enable then
char.Humanoid.PlatformStand = true
char.Humanoid.AutoRotate = false
char.Humanoid.JumpPower = 0
char.Humanoid.Jump = false
else
char.Humanoid.PlatformStand = false
char.Humanoid.AutoRotate = true
char.Humanoid.JumpPower = 50
char.Humanoid.Jump = true
char.Humanoid.EvaluateStateMachine = true
end
end
createHitboxes(true)
setupRagdoll()
task.wait(10)
ragdoll(true)
task.wait(5)
ragdoll(false)
I have found the solution. Had to add a local script which prevents FallingDown and Ragdoll states from being active, this solved the issue completely.
LocalScript:
local function disableps()
local char:CharacterAppearance = script.Parent
local hum:Humanoid = script.Parent.Humanoid
hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
hum:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
end
disableps()
script:Destroy()