Ragdoll Script only working on players and not npcs

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I want to use this script with NPC’s

  1. What is the issue? Include screenshots / videos if possible!

It wont ragdoll NPC’s and will only ragdoll real characters

--> June 6, 2023

--> 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 = false

--> Specific CFrame's I made for the best looking Ragdoll
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(-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)},
	["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)},
}

local ragdollInstanceNames = {
	["RagdollAttachment"] = true,
	["RagdollConstraint"] = true,
	["ColliderPart"] = true,
}

--> Used to trigger Ragdoll
local RagdollValue = Instance.new("BoolValue")
RagdollValue.Name = "IsRagdoll"
RagdollValue.Parent = Character

--> Used for anticheats to prevent flying Ragdolls from getting flagged, might be useful for you.
-------------------------------------------------------------------------------------------------

--> Allows for proper limb collisions
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
	
	local wc = Instance.new("WeldConstraint")
	wc.Part0 = rp
	wc.Part1 = part
	
	wc.Parent = rp
	rp.Parent = part
	print("Colliderpart created")
end

--> Converts Motor6D's into BallSocketConstraints
function replaceJoints()
	for _, motor: Motor6D in pairs(Character:GetDescendants()) do
		if motor:IsA("Motor6D") then
			if not attachmentCFrames[motor.Name] then return end
			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"
			print("new ragdoll attachments")
			createColliderPart(motor.Part1)
			local b = Instance.new("BallSocketConstraint")
			b.Attachment0 = a0
			b.Attachment1 = a1
			b.Name = "RagdollConstraint"
			
			b.Radius = 0.15
			b.LimitsEnabled = true
			b.TwistLimitsEnabled = false
			b.MaxFrictionTorque = 0
			b.Restitution = 0
			b.UpperAngle = 90
			b.TwistLowerAngle = -45
			b.TwistUpperAngle = 45

			if motor.Name == "Neck" then
				b.TwistLimitsEnabled = true
				b.UpperAngle = 45
				b.TwistLowerAngle = -70
				b.TwistUpperAngle = 70
			end
			
			a0.Parent = motor.Part0
			a1.Parent = motor.Part1
			b.Parent = motor.Parent
			print("finished")
		end
	end
	
	Humanoid.AutoRotate = false --> Disabling AutoRotate prevents the Character rotating in first person or Shift-Lock
end

--> Destroys all Ragdoll made instances and re-enables the 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
	
	Humanoid.AutoRotate = true
end

function Ragdoll(value: boolean)
	if value then
		print("dummy ragdoll true")
		replaceJoints() 
		Character:SetAttribute("RagDoll", true)
	else
		print("dummy ragdoll false")
		resetJoints()
		Character:SetAttribute("RagDoll", false)
	end
end

-------------------------------------------------------------------------------------------------
--> Connect the Events
RagdollValue.Changed:Connect(Ragdoll)
Humanoid.Died:Once(function()
	RagdollValue.Value = true
end)
  1. What solutions have you tried so far?

Used Print Debugging and it stopped printing when it was supposed to print “new ragdoll attachments”

Where is the script located, and is it a Server Script or a local one? Ragdoll scripts has 2 variants, one for players, one for NPCs. It seems like this script is only compatible for players;

If you haven’t already, try making it a server script

I have tried the script on an NPC via a server script and the ragdoll on an NPC seems to have worked.

I am assuming you are adding it as a server script as it didn’t seem like a localscript would work since BreakJointsOnDeath being set to false on the client doesn’t prevent it from breaking joints. If you have not tried it on a server script then I recommend doing so!

I am also wondering what rig type the player character and the NPC are.

try this maybe it will work, for server script, umm idk why did it come out like that

local Character = script.Parent
local Humanoid = Character:FindFirstChildOfClass("Humanoid")

Character.Humanoid.BreakJointsOnDeath = false
Character.Humanoid.RequiresNeck = false

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(-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)},
    ["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)},
}

local ragdollInstanceNames = {
    ["RagdollAttachment"] = true,
    ["RagdollConstraint"] = true,
    ["ColliderPart"] = true,
}

local RagdollValue = Instance.new("BoolValue")
RagdollValue.Name = "IsRagdoll"
RagdollValue.Parent = Character

local function createColliderPart(part)
    if not part then return end
    local colliderPart = Instance.new("Part")
    colliderPart.Name = "ColliderPart"
    colliderPart.Size = part.Size / 1.7
    colliderPart.Massless = true
    colliderPart.CFrame = part.CFrame
    colliderPart.Transparency = 1

    local weldConstraint = Instance.new("WeldConstraint")
    weldConstraint.Part0 = colliderPart
    weldConstraint.Part1 = part
    weldConstraint.Parent = colliderPart

    colliderPart.Parent = part
    print("Colliderpart created")
end

local function replaceJoints()
    for _, motor in pairs(Character:GetDescendants()) do
        if motor:IsA("Motor6D") then
            if not attachmentCFrames[motor.Name] then return end
            motor.Enabled = false;
            local attachment0, attachment1 = Instance.new("Attachment"), Instance.new("Attachment")
            attachment0.CFrame = attachmentCFrames[motor.Name][1]
            attachment1.CFrame = attachmentCFrames[motor.Name][2]

            attachment0.Name = "RagdollAttachment"
            attachment1.Name = "RagdollAttachment"
            print("new ragdoll attachments")
            createColliderPart(motor.Part1)
            local ballSocketConstraint = Instance.new("BallSocketConstraint")
            ballSocketConstraint.Attachment0 = attachment0
            ballSocketConstraint.Attachment1 = attachment1
            ballSocketConstraint.Name = "RagdollConstraint"

            ballSocketConstraint.Radius = 0.15
            ballSocketConstraint.LimitsEnabled = true
            ballSocketConstraint.TwistLimitsEnabled = false
            ballSocketConstraint.MaxFrictionTorque = 0
            ballSocketConstraint.Restitution = 0
            ballSocketConstraint.UpperAngle = 90
            ballSocketConstraint.TwistLowerAngle = -45
            ballSocketConstraint.TwistUpperAngle = 45

            if motor.Name == "Neck" then
                ballSocketConstraint.TwistLimitsEnabled = true
                ballSocketConstraint.UpperAngle = 45
                ballSocketConstraint.TwistLowerAngle = -70
                ballSocketConstraint.TwistUpperAngle = 70
            end

            attachment0.Parent = motor.Part0
            attachment1.Parent = motor.Part1
            ballSocketConstraint.Parent = motor.Parent
            print("finished")
        end
    end

    Humanoid.AutoRotate = false
end

local 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

    Humanoid.AutoRotate = true
end

local function Ragdoll(value)
    if value then
        print("Ragdoll aktif")
        replaceJoints()
        Character:SetAttribute("RagDoll", true)
    else
        print("Ragdoll pasif")
        resetJoints()
        Character:SetAttribute("RagDoll", false)
    end
end

RagdollValue.Changed:Connect(Ragdoll)
Humanoid.Died:Connect(function()
    RagdollValue.Value = true
end)

It is a server script and it registers that the value is being changed but it wont ragdoll the npc

Both Are R6 And it is a server script

With your code

i hope it works well for you and i look forward to your continued success!

it does not work well sorry if i didnt specify in the above video but as you can see the npc will just sit like a normal character un ragdolled

sit? what do you mean by that, in the video its normal, he is ragdolling and stands up

sorry i meant stay instead of sit, and also that “ragdoll” your seeing is a mixture of body velocity and bodyrotation. For ragdoll his arms and legs are supposed to flail

local function replaceJoints(character)
    for _, motor in pairs(character:GetDescendants()) do
        if motor:IsA("Motor6D") then
            if not attachmentCFrames[motor.Name] then return end
            motor.Enabled = false
            local attachment0, attachment1 = Instance.new("Attachment"), Instance.new("Attachment")
            attachment0.CFrame = attachmentCFrames[motor.Name][1]
            attachment1.CFrame = attachmentCFrames[motor.Name][2]

            attachment0.Name = "RagdollAttachment"
            attachment1.Name = "RagdollAttachment"
            print("New ragdoll attachments")
            createColliderPart(motor.Part1)
            local hingeConstraint = Instance.new("HingeConstraint")
            hingeConstraint.Attachment0 = attachment0
            hingeConstraint.Attachment1 = attachment1
            hingeConstraint.Name = "RagdollConstraint"

            hingeConstraint.LimitsEnabled = true
            hingeConstraint.UpperAngle = math.rad(45) -- İstenen açıyı ayarlayabilirsiniz
            hingeConstraint.LowerAngle = math.rad(-45) -- İstenen açıyı ayarlayabilirsiniz

            attachment0.Parent = motor.Part0
            attachment1.Parent = motor.Part1
            hingeConstraint.Parent = motor.Parent
            print("Finished")
        end
    end

    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if humanoid then
        humanoid.AutoRotate = false
    end
end

local function ragdollCharacter(character)
    -- Ensure character exists
    if not character or not character:IsA("Model") then
        return
    end

    -- Set RagdollValue
    local ragdollValue = Instance.new("BoolValue")
    ragdollValue.Name = "IsRagdoll"
    ragdollValue.Parent = character

    -- Replace joints for the character
    replaceJoints(character)

    -- Connect Humanoid.Died event to ragdoll the character
    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if humanoid then
        humanoid.Died:Connect(function()
            ragdollValue.Value = true
        end)
    end
end

-- Ragdoll NPC
ragdollCharacter(script.Parent)

-- Ragdoll Players
game.Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        ragdollCharacter(character)
    end)
end)

try this if it does not work, thats all i can do sorry about that.

1 Like

nah it still wont work, thanks for trying though

1 Like

this is my real last time u can try this, i added BallSocketConstraint for hands and legs

local function replaceJoints()
    for _, motor in pairs(Character:GetDescendants()) do
        if motor:IsA("Motor6D") then
            if not attachmentCFrames[motor.Name] then return end
            motor.Enabled = false
            local attachment0, attachment1 = Instance.new("Attachment"), Instance.new("Attachment")
            attachment0.CFrame = attachmentCFrames[motor.Name][1]
            attachment1.CFrame = attachmentCFrames[motor.Name][2]

            attachment0.Name = "RagdollAttachment"
            attachment1.Name = "RagdollAttachment"
            print("new ragdoll attachments")
            createColliderPart(motor.Part1)
            local ballSocketConstraint = Instance.new("BallSocketConstraint")
            ballSocketConstraint.Attachment0 = attachment0
            ballSocketConstraint.Attachment1 = attachment1
            ballSocketConstraint.Name = "RagdollConstraint"

            ballSocketConstraint.Radius = 0.15
            ballSocketConstraint.LimitsEnabled = true
            ballSocketConstraint.TwistLimitsEnabled = false
            ballSocketConstraint.MaxFrictionTorque = 0
            ballSocketConstraint.Restitution = 0
            ballSocketConstraint.UpperAngle = 90
            ballSocketConstraint.TwistLowerAngle = -45
            ballSocketConstraint.TwistUpperAngle = 45

            if motor.Name == "Neck" then
                ballSocketConstraint.TwistLimitsEnabled = true
                ballSocketConstraint.UpperAngle = 45
                ballSocketConstraint.TwistLowerAngle = -70
                ballSocketConstraint.TwistUpperAngle = 70
            end

            attachment0.Parent = motor.Part0
            attachment1.Parent = motor.Part1
            ballSocketConstraint.Parent = motor.Parent
            print("finished")

            -- El ve bacaklara BallSocketConstraint ekle
            if motor.Name == "Left Shoulder" or motor.Name == "Right Shoulder" or
               motor.Name == "Left Hip" or motor.Name == "Right Hip" then
                local ballSocket = Instance.new("BallSocketConstraint")
                ballSocket.Attachment0 = attachment0
                ballSocket.Attachment1 = attachment1
                ballSocket.Name = motor.Name .. "BallSocket"
                ballSocket.Parent = motor.Parent
            end
        end
    end

    Humanoid.AutoRotate = false
end