Adding Ragdoll Effect

I am working on adding a feature in my Roblox game I’m where players get rag dolled when they touch a hit box generated by a VFX. I want to make sure that when the VFX appears and its hit box collides with another player, it triggers a knock back effect that rag dolls the player. Preformatted textelow is my current script, which includes creating the VFX, attaching it to the player, and handling the knock back. I previously had a ragdoll script but when they rag dolled they fell on the floor but would start glitching and sometimes fly into the air. I tried everything to fix it, Youtube Videos, DevForum, my friends and they don’t fix the issue. So I deleted it thinking of coming to it later and now here I am.

List item

local VFXModelID = 18250555736

local replicatedStorage = game:GetService("ReplicatedStorage")
local tweenService = game:GetService("TweenService")
local debris = game:GetService("Debris")
local players = game:GetService("Players")
local insertService = game:GetService("InsertService")

local workspace = game:GetService("Workspace")

local cooldowns = {}

local animationId = "rbxassetid://18242617741"

local knockbackForce = 5 

local function disableControls(player)
	local character = player.Character
	if character then
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
			humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		end
		for _, tool in pairs(character:GetChildren()) do
			if tool:IsA("Tool") then
				tool.Enabled = false
			end
		end
		character:SetAttribute("Attacking", true)
		character:SetAttribute("Punching", true)
	end
end

local function enableControls(player)
	local character = player.Character
	if character then
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid.WalkSpeed = 16
			humanoid.JumpPower = 50
			humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
		end
		for _, tool in pairs(character:GetChildren()) do
			if tool:IsA("Tool") then
				tool.Enabled = true
			end
		end
		character:SetAttribute("Attacking", false)
		character:SetAttribute("Punching", false)
	end
end

local function applyKnockback(enemyHum, direction)
	local enemyHumRp = enemyHum.Parent:FindFirstChild("HumanoidRootPart")
	if enemyHumRp then
		local force = Instance.new("BodyVelocity", enemyHumRp)
		force.MaxForce = Vector3.new(1, 1, 1) * math.huge
		force.Velocity = direction * knockbackForce
		debris:AddItem(force, 0.35)
	end
end

local function createHitbox(vfxClone)
	local hitbox = Instance.new("Part")
	hitbox.Size = Vector3.new(10, 10, 10) 
	hitbox.Anchored = true
	hitbox.CanCollide = false
	hitbox.Transparency = 1
	hitbox.Color = Color3.new(1, 0, 0) 
	hitbox.Name = "Hitbox"
	hitbox.CFrame = vfxClone.CFrame
	hitbox.Parent = vfxClone
	return hitbox
end

local function getAllParticleEmitters(vfxClone)
	local emitters = {}
	for _, descendant in pairs(vfxClone:GetDescendants()) do
		if descendant:IsA("ParticleEmitter") then
			table.insert(emitters, descendant)
		end
	end
	for _, attachment in pairs(vfxClone:GetDescendants()) do
		if attachment:IsA("Attachment") then
			for _, descendant in pairs(attachment:GetDescendants()) do
				if descendant:IsA("ParticleEmitter") then
					table.insert(emitters, descendant)
				end
			end
		end
	end
	return emitters
end

local function attachVFXToPlayer(player)
	local character = player.Character
	if not character then
		warn("Character not found for player: " .. player.Name)
		return
	end

	local vfxModel = insertService:LoadAsset(VFXModelID)
	local vfxPart = vfxModel:FindFirstChildWhichIsA("Part")
	if not vfxPart then
		warn("VFX part not found in the model!")
		return
	end

	local vfxClone = vfxPart:Clone()
	vfxClone.Anchored = false
	vfxClone.CanCollide = true
	vfxClone.Transparency = 1 
	vfxClone.Name = "VFXClone"

	local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
	if humanoidRootPart then
		vfxClone.Parent = character
		vfxClone.CFrame = humanoidRootPart.CFrame

		local weld = Instance.new("WeldConstraint")
		weld.Part0 = vfxClone
		weld.Part1 = humanoidRootPart
		weld.Parent = vfxClone

		local hitbox = createHitbox(vfxClone)

		local highlight = Instance.new("Highlight")
		highlight.Adornee = vfxClone
		highlight.FillColor = Color3.new(1, 1, 0)
		highlight.FillTransparency = 0.5
		highlight.OutlineTransparency = 1
		highlight.Parent = vfxClone

		local emitters = getAllParticleEmitters(vfxClone)

		disableControls(player)

		print("VFX attached to player: " .. player.Name)

		delay(1.49, function()
			for _, emitter in pairs(emitters) do
				emitter.Enabled = true
			end

			hitbox.Touched:Connect(function(hit)
				if hit:IsA("BasePart") and hit.Parent ~= character then
					local enemyHum = hit.Parent:FindFirstChildOfClass("Humanoid")
					if enemyHum then
						local enemyChar = enemyHum.Parent
						local enemyHumRp = enemyChar:FindFirstChild("HumanoidRootPart")
						if enemyHumRp then
							local direction = (enemyHumRp.Position - hitbox.Position).Unit
							local knockback = direction * knockbackForce
							applyKnockback(enemyHum, knockback)
						end
					end
				end
			end)

			delay(4, function()
				vfxClone:Destroy()
				enableControls(player)
			end)
		end)
	else
		warn("HumanoidRootPart not found for player: " .. player.Name)
	end
end

local toggleVFXEvent = replicatedStorage:FindFirstChild("ToggleVFX")
if not toggleVFXEvent then
	toggleVFXEvent = Instance.new("RemoteEvent")
	toggleVFXEvent.Name = "ToggleVFX"
	toggleVFXEvent.Parent = replicatedStorage
end

toggleVFXEvent.OnServerEvent:Connect(function(player)
	local playerName = player.Name
	local currentTime = tick()

	if cooldowns[playerName] and (currentTime - cooldowns[playerName]) < 5 then
		local timeLeft = 5 - (currentTime - cooldowns[playerName])
		warn(playerName .. " is on cooldown. Time left: " .. math.ceil(timeLeft) .. " seconds.")
		return
	end

	disableControls(player)

	local character = player.Character
	if character then
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			local animation = Instance.new("Animation")
			animation.AnimationId = animationId
			local animationTrack = humanoid:LoadAnimation(animation)
			animationTrack.Looped = false
			animationTrack:Play()
			animationTrack:AdjustSpeed(1.5)

			delay(1.49, function()
				attachVFXToPlayer(player)
			end)

			cooldowns[playerName] = currentTime
		else
			warn("Humanoid not found for player: " .. player.Name)
		end
	else
		warn("Character not found for player: " .. player.Name)
	end
end)
1 Like

Instead of changing humanoid state just set platform stand to true