Ragdolls seemingly not using the physics state

I have a working ragdoll system for players in my game, but for some reason the NPCs fly up for seemingly no real reason and after trying countless fixes it appears to be no luck. Is there anyone who has an r6 ragdoll system who has dealt with this before? I provided a video below of the situation: https://youtu.be/auImHAM6eTw

I also provided code of the script inside the NPC itself, and the module in ServerScriptService:

--//RagdollServerNPC

local character = script.Parent
local Torso = character.Torso
local Humanoid = character.Humanoid
local RagdollTimer = character.RagdollTime
local alignOrientation = character.HumanoidRootPart.AlignOrientation
local ragdollModule = require(game.ServerScriptService.Ragdoll.RagdollModule)
local ragdolled = false

Humanoid.BreakJointsOnDeath = false
Humanoid.RequiresNeck = false



while task.wait(0.1) do
	if character.Parent == workspace.Characters and character.HumanoidRootPart:GetNetworkOwner() ~= nil then
		character.HumanoidRootPart:SetNetworkOwner(nil)
	end
	
	if Humanoid.Health > 0 then
		if RagdollTimer.Value > 0 then
			RagdollTimer.Value -= 0.1
			if ragdolled == false then
				ragdolled = true
				alignOrientation.Enabled = false
				ragdollModule.replaceJoints(character)
				character.HumanoidRootPart.AssemblyLinearVelocity = Vector3.zero
				Humanoid.PlatformStand = true
				Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
				Humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, false)
				Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
			end
		elseif RagdollTimer.Value < 0 and ragdolled == true then
			ragdolled = false
			alignOrientation.Enabled = true
			ragdollModule.resetJoints(character)
			Humanoid.PlatformStand = false
			Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
			Humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, true)
			Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
		end
	else
		if ragdolled == false then
			ragdolled = true
			alignOrientation.Enabled = false
			ragdollModule.replaceJoints(character)
			character.HumanoidRootPart.AssemblyLinearVelocity = Vector3.zero
			Humanoid.PlatformStand = true
			Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
			Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
			Humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, false)
		end
	end
end

--//RagdollModule

local module = {}

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,
	["RootPartWeld"] = true,
	["BallSocketConstraint"] = true
}

function module.replaceJoints(Character:Model)
	local weld = Instance.new("WeldConstraint")
	weld.Name = "RootPartWeld"
	weld.Parent = Character.HumanoidRootPart
	Character.Torso.Position = Character.HumanoidRootPart.Position
	weld.Part0 = Character.HumanoidRootPart
	weld.Part1 = Character.Torso
	Character.HumanoidRootPart.RootJoint.Enabled = false
	
	for _, motor: Motor6D in Character:GetDescendants() do
		if motor:IsA("Motor6D") then
			if not attachmentCFrames[motor.Name] then return end
			local socket = Instance.new("BallSocketConstraint")
			local a1 = Instance.new("Attachment")
			local a2 = Instance.new("Attachment")
			a1.Name = "RagdollAttachment"
			a2.Name = "RagdollAttachment"
			a1.Parent = motor.Part0
			a2.Parent = motor.Part1
			socket.Parent = motor.Parent
			socket.Attachment0 = a1
			socket.Attachment1 = a2
			a1.CFrame = motor.C0
			a2.CFrame = motor.C1
			socket.LimitsEnabled = true
			socket.TwistLimitsEnabled = true
			local part = motor.Part1
			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
			motor.Enabled = false
		end
	end
	
end

function module.resetJoints(Character:Model)
	if Character.Humanoid.Health < 1 then return end
	
	Character.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
	Character.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, true)
	Character.Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
	
	for _, instance in Character:GetDescendants() do
		if ragdollInstanceNames[instance.Name] then
			instance:Destroy()
		end
		
		if instance:IsA("Motor6D") then
			instance.Enabled = true;
		end
	end
	
	if Character:FindFirstChild("HumanoidRootPart") then
		Character.HumanoidRootPart.RootJoint.Enabled = true
	end
end

function module.setRagdollTime(character:Model,ragdollTime:number)
	if character:FindFirstChild("RagdollTime") and not character.HumanoidRootPart:FindFirstChild("IceBlock") then
		if character.RagdollTime.Value < ragdollTime then
			character.RagdollTime.Value = ragdollTime
		end
	end
end

return module

Can someone please provide a fix for this bug, it makes fighting the NPCs very infuriating at times.

1 Like

I believe you must set the humanoid the physics state on both the client and the server

This is for NPCs though, I already set this to physics on player ends but doing so for NPCs via script seems to not be effective

try connecting to humanoid.StateChanged and printing if its really exiting the physics state when the bug occurs