Issues with ragdoll

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:

  1. The server script firstly does quick setup for the ragdoll (hitboxes and constraints)

  2. Every 5 seconds server script ragdolls or unragdolls the character by calling function ragdoll()

  3. The ragdoll() function enables or disables the motors

  4. The ragdoll() function forces character to jump if the Enable argument is false

  5. The ragdoll() function sets the PlatformStand to true

  6. The ragdoll() function sets character’s AutoRotate to false

  7. The ragdoll() function sets the JumpPower to 0 to prevent jumping while in ragdoll.

Server 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

1 Like

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)