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)
2 Likes

Please, someone (limit messages)