How to make ragdoll when got hit by tool?

Hello! I’m trying to make a ragdoll effect when a player gets hit by a tool. Could someone explain how to set this up in Roblox Studio? I’d really appreciate your help!

Also, here are my scripts for tool

Knockback

local cooldown = false


script.Parent.Activated:Connect(function()

	if cooldown then return end

	cooldown = true


	local ray = Ray.new(script.Parent.Parent.HumanoidRootPart.Position, script.Parent.Parent.HumanoidRootPart.Position + script.Parent.Parent.HumanoidRootPart.CFrame.LookVector * 5)

	local part = workspace:FindPartOnRay(ray, script.Parent.Parent)


	if part then

		local humanoid = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid")

		if humanoid then

			humanoid.Parent.HumanoidRootPart.Velocity = script.Parent.Parent.HumanoidRootPart.CFrame.LookVector * 100 + Vector3.new(0, 50, 0)
		end
	end


	wait(1)

	cooldown = false
end)

just script

char = script.Parent.Parent.Parent.Character
joints = {}
glues = {}
humanoid = nil

function onSelected(mouse)
	local torso = char:findFirstChild("Torso")
	if torso == nil then return end
	local c = torso:GetChildren()
	for i = 1, #c do
		if c[i]:IsA("JointInstance") then
			table.insert(joints,c[i])
			local glue = Instance.new("Rotate")
			glue.C0 = c[i].C0
			glue.C1 = c[i].C1
			glue.Part0 = c[i].Part0
			glue.Part1 = c[i].Part1
			glue.Name = c[i].Name
			table.insert(glues,glue)
			c[i].Part1.CanCollide = true
			c[i].Parent = nil
			glue.Parent = torso
		end
	end
	local k = char:GetChildren()
	for i = 1,#k do
		if k[i].className == "Hat" then
			if k[i]:findFirstChild("Handle") ~= nil then
				local weld = Instance.new("Weld")
				weld.Name = "Weld"
				weld.Part0 = char.Head
				weld.Part1 = k[i].Handle
				weld.C0 = char.Head.CFrame:inverse()
				weld.C1 = k[i].Handle.CFrame:inverse()
				weld.Parent = k[i].Handle
			end
		end
	end
	humanoid = char:findFirstChild("Humanoid")
	if humanoid ~= nil then humanoid.Parent = nil end
end

function onDeselected(mouse)
	for i = 1, #glues do
		glues[i]:remove()
	end
	for i = 1, #joints do
		joints[i].Parent = char:findFirstChild("Torso")
	end
	--[[local k = char:GetChildren()
	for i = 1,#k do
		if k[i].className == "Hat" then
			if k[i]:findFirstChild("Handle") ~= nil then
				k[i].Handle.Weld:remove()
			end
		end
	end]]
	if humanoid ~= nil then humanoid.Parent = char end
end

--script.Parent.Selected:connect(onSelected)
--script.Parent.Deselected:connect(onDeselected)

script.Parent.Equipped:Connect(onSelected)
script.Parent.Unequipped:Connect(onDeselected)

Server

local punch = script.Parent
local remote = punch.Remote
local hitpart = punch.HitPart
local humanoidlist = {}
local touch
local debris = game:GetService("Debris")
local Players = game:GetService("Players")
local cooldownTime = 3  -- Время восстановления

function CheckHumanoid(hum)
	for _, v in pairs(humanoidlist) do
		if v == hum then
			return true
		end
	end
	return false
end

function Velocity(x, y, z, maxtorque, maxforce, vector, hit)
	local attachment = Instance.new("Attachment", hit)
	local linear = Instance.new("LinearVelocity", hit)
	linear.MaxForce = maxforce
	linear.Attachment0 = attachment
	linear.RelativeTo = Enum.ActuatorRelativeTo.World
	linear.VectorVelocity = vector

	local angular = Instance.new("AngularVelocity", hit)
	angular.MaxTorque = maxtorque
	angular.AngularVelocity = Vector3.new(x, y, z)
	angular.Attachment0 = attachment
	angular.RelativeTo = Enum.ActuatorRelativeTo.Attachment0

	debris:AddItem(angular, 0.5)
	debris:AddItem(linear, 0.5)
	debris:AddItem(attachment, 0.5)
end

local function initialize(char)
	print("Initializing punch for character:", char.Name)
	local hrp = char:FindFirstChild("HumanoidRootPart")

	local weld = hitpart:FindFirstChild("Weld")
	if weld then
		weld.Part0 = char:FindFirstChild("Right Arm")
		weld.Part1 = hitpart
	end

	punch.Enabled = true 
	local humanoid = char:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.Died:Connect(function()
			punch.Enabled = false
			if touch then
				touch:Disconnect()
				touch = nil
			end
		end)
	end
end

function ApplyRagdoll(character)
	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if humanoid and humanoid.Health > 0 then
		humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	end

	for _, part in pairs(character:GetChildren()) do
		if part:IsA("BasePart") then
			part:SetNetworkOwner(nil)
			if part:FindFirstChildOfClass("Motor6D") then
				local constraint = Instance.new("BallSocketConstraint")
				constraint.Parent = part
				constraint.Attachment0 = Instance.new("Attachment", part)
				constraint.Attachment1 = Instance.new("Attachment", part.Parent:FindFirstChild(part.Name))
				debris:AddItem(constraint, 2)
			end
		end
	end

	task.wait(2)

	if humanoid and humanoid.Health > 0 then
		humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
	end

	for _, part in pairs(character:GetChildren()) do
		if part:IsA("BasePart") then
			part:SetNetworkOwner(Players:GetPlayerFromCharacter(character))
		end
	end
end

function startCooldown(player)
	player:SetAttribute("CooldownActive", true)
	punch.Enabled = false

	local interval = 0.1
	local steps = cooldownTime / interval
	for i = 1, steps do
		punch.Name = "[" .. string.format("%.1f", cooldownTime - (i * interval)) .. "]"
		task.wait(interval)
	end

	punch.Name = "Punch"
	punch.Enabled = true
	player:SetAttribute("CooldownActive", false)
end

remote.OnServerInvoke = function(plr, action)

	if action == "Swing" then
		
		if not plr:GetAttribute("CooldownActive") then
			--here is fine
			punch.Enabled = false
			plr:SetAttribute("CooldownActive", true)
			
			delay(0.2, function()
				touch = hitpart.Touched:Connect(function(hit)
					--wait nvm i forgot that i need to kill something
					--where are the dummies?
					--ok
					--yes
					-- i think its fine if it works on rig 
					--adding a spawnpoint so that i can reach it faster
					--you can remove it afterwards
					if hit and hit.Parent then
						local hum = hit.Parent:FindFirstChildOfClass("Humanoid")
						if hum then
							local check = CheckHumanoid(hum)
							local otherhrp = hit.Parent:FindFirstChild("HumanoidRootPart")
							if otherhrp then
								local delta = otherhrp.Position - hitpart.Position
								if not check then
									table.insert(humanoidlist, hum)
									Velocity(0, 0, 25, 40, 9999999, delta * 10, otherhrp)
									hum:TakeDamage(20)
									hitpart.Hit:Play()
									ApplyRagdoll(hit.Parent)

									-- Add creator tag
									local creatorTag = Instance.new("ObjectValue")
									creatorTag.Name = "creator"
									creatorTag.Value = plr
									creatorTag.Parent = hum
									debris:AddItem(creatorTag, 2)  -- Adjust duration as needed

									task.wait(1)
									humanoidlist = {}
								end
							end
						end
					end
				end)
			end)

			delay(1, function()
				if touch then
					touch:Disconnect()
					touch = nil
				end
			end)

			startCooldown(plr)
			return true
		end
	end
end

punch.Equipped:Connect(function()
	local char = punch.Parent
	print("Punch equipped by:", char.Name)
	initialize(char)
end)

Players.PlayerAdded:Connect(function(player)
	-- Добавляем атрибут для кулдауна
	player:SetAttribute("CooldownActive", false)

	player.CharacterAdded:Connect(function(character)
		task.wait(1)
		if punch.Parent ~= character then
			print("Re-parenting punch to character's right arm.")
			--punch.Parent = character:FindFirstChild("Right Arm")-- here issue
		end

		initialize(character)
	end)
end)

punch.SwingSound.OnServerEvent:Connect(function(plr)
	hitpart.Swing:Play()
end)

Toolhandler

local tool = script.Parent
local debounce = true
tool.Activated:Connect(function()
	if debounce == true then
		debounce = false
		wait(tool.Cooldown.Value)
		debounce = true
	end
end)

tool.HitPart.Touched:Connect(function(hit) -- Ragdoll
	if debounce == false then
		script.Disabled = true
		local Ragdoll = require(game.ServerScriptService.Module)
		Ragdoll.Start(hit.Parent)
		local force = Instance.new("BodyVelocity", hit.Parent.HumanoidRootPart)
		force.MaxForce = Vector3.new(2,2,2) * math.huge
		local direction = (hit.Parent.HumanoidRootPart.CFrame.Position - tool.Parent.HumanoidRootPart.CFrame.Position).Unit
		force.Velocity = (direction + Vector3.new(0,1,0)).Unit * 25
		local rotation = Instance.new("BodyAngularVelocity", hit.Parent.HumanoidRootPart)
		rotation.AngularVelocity = Vector3.new(1,1,1) * math.pi * 5
		rotation.MaxTorque = Vector3.new(2,2,2) * math.huge
		rotation.P = 5000
		--tool.Handle.Slap:Play()--
		wait(0.35)
		force:Destroy()
		rotation:Destroy()
		script.Disabled = false
		wait(math.random(1.25, 3.15))
		Ragdoll.Stop(hit.Parent)
	end
end)

client

local punch = script.Parent
local hitpart = punch.HitPart
local anim = punch:WaitForChild("Animations")
local remote = punch:WaitForChild("Remote")
local player = game:GetService("Players").LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local lhum = char:WaitForChild("Humanoid")
local sound = punch:WaitForChild("SwingSound")
local equipped = false
local loadswing, loadidle

punch.Equipped:Connect(function(mouse)
	equipped = true
	loadswing = lhum:LoadAnimation(anim:WaitForChild("Swing1"))
	loadidle = lhum:LoadAnimation(anim:WaitForChild("Idle"))
	loadidle:Play()

	punch.Unequipped:Connect(function()
		equipped = false
		if loadswing then
			loadswing:Stop()
		end
		if loadidle then
			loadidle:Stop()
		end
	end)
end)

punch.Activated:Connect(function()
	if punch.Enabled and equipped then
		loadswing:Play()
		local invoke = remote:InvokeServer("Swing")

		if invoke == true then
			loadswing.KeyframeReached:Connect(function(name)
				if name == "Sound" then
					sound:FireServer()
				end
			end)
		end
	end
end)

localscript

char = script.Parent.Parent.Parent.Character

function onSelected(mouse)
	workspace.CurrentCamera.CameraSubject = char:findFirstChild("Torso")
end

function onDeselected(mouse)
	wait()
	workspace.CurrentCamera.CameraSubject = char:findFirstChild("Humanoid")
end

--script.Parent.Selected:connect(onSelected)
--script.Parent.Deselected:connect(onDeselected)

--script.Parent.Equipped:Connect(onSelected)
--script.Parent.Unequipped:Connect(onDeselected)

you already have an ApplyRagdoll function
try printing inside to verify it gets called correctly

if the ragdoll function doesnt work then try replacing with some ragdoll module
and these might be better anyways because they have support for unragdoll