Hitbox code not working as intended

I’m trying to make some hitbox detection but I’m unable to figure out a way to detect the collision correctly, .Touched wont work because of its funky system, it only really detects when you move in it, GetTouchingParts() wont work because my hitbox is non-collidable, i don’t know what else there is. Please help!

local AU = game.ReplicatedStorage["Abillity Used"]
local TS = game:GetService("TweenService")
local List = require(game.ServerScriptService.Abilitys)
local hitboxes = game.ReplicatedStorage.Hitboxes
AU.OnServerEvent:Connect(function(player, key)
	print(key == Enum.UserInputType.MouseButton1)
	if key == Enum.UserInputType.MouseButton1 then
		print("hi")
		local dmg = List.killers.groovy.m1.dmg
		local cd = 0.8
		local Clones = {}
		local attacked = {}
		local function contains(tbl, value)
			for _, v in pairs(tbl) do
				if v == value then
					return true
				end
			end
			return false
		end
		for i = 1, 5 do
			local cframe = player.Character:WaitForChild("HumanoidRootPart").CFrame
			clone = hitboxes.Melee.M1:Clone() 
			clone.Parent = workspace
			clone.CFrame = cframe
			clone.CFrame = cframe * CFrame.new(0, 0, -2)
			task.wait(0.01)
			table.insert(Clones, clone)
		end
		for _, clone in pairs(Clones) do
			local touchingParts = clone:GetTouchingParts()

			for _, part in pairs(touchingParts) do
				if part.Parent:FindFirstChild("Humanoid") then
					if not contains(attacked, part.Parent) then
						table.insert(attacked, part.Parent)
						part.Parent.Humanoid.Health -= dmg
					end
				end
			end
		end
		for idx, clone in pairs(Clones) do
			wait(0.01)
			clone.CanTouch = false
			wait(0.18)
			local tween = TS:Create(clone, TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0), {Transparency = 1})
			tween:Play()
			tween.Completed:Wait()
			clone:Destroy()
		end
	else
		print("no working")
	end
end)

hello. i am new to scripting but i will still try to help how i can

so first of all the “other option” youre looking for is workspace:GetPartBoundsInBox to use it you simply pass in a cframe (location of the hitbox), a vector3 (size of the hitbox), and overlap params, which in your case you would put the attacker in. this is called a spatial query, and it returns a table of the parts inside an area. heres a short example of how you would use it.

local Params_For_SpatialQuery = OverlapParams.new() --Create new overlap parameters.

Params_For_SpatialQuery:AddToFilter(workspace.Folder_Of_Things_To_Ignore) --Add a folder of things to ignore to the filter of the parameters.

local function Print_Parts_In_An_Area()
	local PartsRetreived = workspace:GetPartBoundsInBox(CFrame.new(0, 8, 0), Vector3.new(12, 12, 12), Params_For_SpatialQuery) --Gets the parts inside an area, and then stores them in a table.
	
	for index, value in pairs(PartsRetreived) do
		print(value.Name .. " is in the box!") --For each value in the table of PartsRetreived, print the name of the value
	end
end

while true do --Call the function once every second.
	Print_Parts_In_An_Area()
	task.wait(1)
end

This script would get all the parts inside this area (image below) and then print them, once every second.

image