Im sharing the hitbox module i use because im bored (very simple) also i would like improvements

I made a hitbox module, not as good as something like raycastv4 but its slightly easier to use than making all of those attachments

I use close range for this (melee weapons)

to use this just put any part into the function :Start with the callback with damage, heal, whatever, raycastparams and settings (settings in the script)

CODE:

local function len(Table)
	local counter = 0 
	for _, v in pairs(Table) do
		counter =counter + 1
	end
	return counter
end

local module = {}

module.RunningHitboxes = {}

function module:Start(
	hitbox:Instance,callback,params:RaycastParams,
	Settings:{["IsSphere?"]:boolean,
		["AcctuallRendering?"]:boolean,
		["Radius"]:number,["Size"]:Vector3,
		["Pos"]:CFrame|Vector3,
		["Ofset?"]:Vector3,
		["PartForOfset?"]:Instance,
		["db"]:number}
)
	--settings perams explained:
	--IsSphere? is for if the hitbox should detect in a box shape or Sphere shape, If not put into settings it will default as False
	--AcctuallRendering? if true the hitbox pos and size will be the same as the hitbox(:Instance sent as first peramater) defaults as False
	--Raduis is the Spheres size if it is rendered as sphere. Not needed if IsSphere is false
	--Size is the size of the hitbox in a Vector3
	--Pos is either the position:Vector3 of the Sphere or the CFrame of the box --SPECIFIC POSITION NOT OFSET
	--db is the amount of time between each individual player hit. if negative/nonexistant the cooldown is inf without waiting
	--PartForOfset is the part for the ofset
	--Ofset the ofset for the part needing ofset

	if not self.RunningHitboxes[hitbox] then 
		print("loaded hitbox",self.RunningHitboxes,hitbox)
		self.RunningHitboxes[hitbox] = {["settings"] = {}}
	end
	self.RunningHitboxes[hitbox]["callback"] = callback
	self.RunningHitboxes[hitbox]["params"] = params
	self.RunningHitboxes[hitbox]["settings"] = Settings
	self.RunningHitboxes[hitbox]["Hitdb"] = {}

	self.ToggleAppropeatleyRS()
end

function module:CreateHitbox(hitboxPart:Instance)
	print("depreceated")
	return hitboxPart
end

function module:Stop(hitbox:Instance)
	if self.RunningHitboxes[hitbox] then
		self.RunningHitboxes[hitbox] = nil
	end
	self.ToggleAppropeatleyRS()
end

local RSrunning = false
local RSconnection = nil

function module.ToggleAppropeatleyRS()
	if len(module.RunningHitboxes) < 1 then-- it is 0
		if RSrunning then
			module.StopRS()
		end
	else--it is not 0 (eg 1-10000)
		if not RSrunning then 
			module.StartRS()
		end
	end
end

function module.StopRS()
	RSrunning = false
	print("Stopping RS",len(module.RunningHitboxes))
	RSconnection:Disconnect()
end
function module.StartRS()
	RSrunning = true
	print("Starting RS",len(module.RunningHitboxes))
	RSconnection = game["Run Service"].RenderStepped:Connect(module.RunServiceFrame)
end
--[[
Settings:{["IsSphere?"]:boolean,
	["AcctuallRendering?"]:boolean,
	["Radius"]:number,["Size"]:Vector3,
	["Pos"]:CFrame|Vector3,
	["Ofset?"]:Vector3,
	["PartForOfset?"]:Instance,
	["db"]:number}
	
	]]
function module.RunServiceFrame()
	if len(module.RunningHitboxes) < 1 then warn("RunningTable smaller than 1") return end

	for i,v in module.RunningHitboxes do
		if not i then warn("hitbox doesnt exist??") continue end
		if not i:IsA("BasePart") then warn("hitbox is not a basepart") continue end
		local settings = v.settings

		if len(settings) == 0 then
			warn("PlayerNote: STOP FLICKING SN:no settings????..(hitboxParent: "..i.Parent.Name..",hitboxParentParent: "..i.Parent.Parent.Name..")")
			continue
		end

		if not game.Players.LocalPlayer.Character:FindFirstChild("Ragdolled") then module:Stop(v.hitbox) return end
		if game.Players.LocalPlayer.Character:FindFirstChild("Ragdolled").Value then module:Stop(v.hitbox) return end

		if settings["AcctuallRendering?"] then
			settings["Pos"] = i.CFrame
			settings["Size"] = i.Size
		end

		if settings["PartForOfset?"] then
			local ofsetPos = settings["PartForOfset?"].CFrame
			local ofset = (typeof(settings["Ofset?"]) == "CFrame" and settings["Ofset?"] or CFrame.new(settings["Ofset?"]))
			--print(Vector3.new(ofset),ofsetPos,ofsetPos * Vector3.new(ofset))

			local newCFrame = ofsetPos * ofset
			settings["Pos"] = newCFrame
		end

		if not settings["Pos"] then 
			local warnstring = "PlayerNote: how SN:no pos?? (hitboxParent: "..i.Parent.Name..",hitboxParentParent: "..i.Parent.Parent.Name..") "
			for i,v in settings do
				warnstring = warnstring.." "..i.. " : ".. tostring(v)
			end
			warn(warnstring)
			continue end

		local partsFound = {}

		if settings["IsSphere?"] then 
			local Pos = (typeof(settings["Pos"])) == "Vector3" and settings["Pos"] or settings["Pos"].Position
			partsFound = workspace:GetPartBoundsInRadius(Pos, settings["Radius"], v["params"])
		else
			local Pos = (typeof(settings["Pos"])) == "CFrame" and settings["Pos"] or CFrame.new(settings["Pos"])
			partsFound = workspace:GetPartBoundsInBox(Pos, settings["Size"], v["params"])
		end

		local Hit_HumFound:{[BasePart]:Humanoid} = {}

		local detectedHumanoid = false
		for _,part in partsFound do
			local hum = part.Parent:FindFirstChild("Humanoid")

			if not hum then continue end
			detectedHumanoid = true
			if Hit_HumFound[hum] then continue end

			local waiting = true
			if v["Hitdb"][hum] then
				if not settings["db"] then continue end
				if settings["db"] < 0 then continue end

				local now = tick()
				local stored = v["Hitdb"][hum]

				local difference = (now - stored)
				print(difference)
				if difference >= settings["db"] then
					waiting = false
					v["Hitdb"][hum] = nil
				end
			else
				waiting = false
			end
			if waiting then continue end

			Hit_HumFound[hum] = part
			v["Hitdb"][hum] = tick()
		end

		if game.ReplicatedStorage.Settings_preferences.HitboxesEnabled.Value then --REMOVE THIS YALL IF YOU DONT GOT THIS BOOLVALUE

			local hitboxview = Instance.new("Part")
			--print(len(Hit_HumFound))
			hitboxview.BrickColor = (not detectedHumanoid and BrickColor.new("Bright red")) or BrickColor.new("Bright green")--if hit its green otherwise red
			hitboxview.Anchored = true
			hitboxview.CanCollide = false
			hitboxview.CanQuery = false
			hitboxview.CanTouch = false
			hitboxview.CastShadow = false
			hitboxview.Size = (settings["IsSphere?"] and Vector3.new(settings.Radius,settings.Radius,settings.Radius) or settings.Size)--if issphere its a sphere otherwise not
			hitboxview.CFrame = (typeof(settings["Pos"])) == "CFrame" and settings["Pos"] or CFrame.new(settings["Pos"])
			hitboxview.Shape = (settings["IsSphere?"] and Enum.PartType.Ball or Enum.PartType.Block)--if IsSphere then ball else block
			hitboxview.Transparency = 0
			hitboxview.Material = Enum.Material.ForceField

			--if detectedHumanoid then 
			--	--hitboxview.Size = hitboxview.Size + Vector3.new(.2,.2,.2) 
			--	hitboxview.Material = Enum.Material.SmoothPlastic
			--	hitboxview.Transparency = .6
			--end

			hitboxview.Parent = workspace.Clutter
			game.Debris:AddItem(hitboxview,2)
		end

		for HitHum,HitPart in Hit_HumFound do
			v["callback"](HitPart,HitHum)
		end
	end
end

print("Hitboxes required SEP?")

--if callback then
--	callback(HitPart,HitHum)--base hit callback
--end

return module

This is an example of usage

--this example makes the part Specified the hitbox,
local callback = function(HitPart:Part,HitHum:Humanoid)
HitHum:TakeDamage(10)
end
RequiredModule:Start(Workspace.Part,callback,raycastparams.new(),{["AcctuallRendering?"] = true ["db"] = -1})
--this example makes the hitbox an ofset to the characters torso
local callback = function(HitPart:Part,HitHum:Humanoid)
HitHum:TakeDamage(10)
end
RequiredModule:Start(Workspace.Part,callback,raycastparams.new(),{["Size"] = Vector3.new(5,5,5),     ["Ofset?"] = CFrame.new(0,0,-3),["PartForOfset?"] = char.HumanoidRootPart,["db"] = -1})
     
task.Wait(10)
RequiredModule:Stop(Workspace.Part)
--btw since these both use the same Workspace.Part, they will both override each other (or it will           completely break idk
1 Like

ngl i prob should have put it into a different channel because this code is kinda cooked

Can you please add ```lua instead of plain ``` ?
Thanks.
Also why are you using methods when you never use self?
You literally waste an entire register inside a function for nothing that stays there and wastes memory.

2 Likes

i was just doing 5 spaces…
thanks for telling me about ```lua

wow code

i never really dabbled into using self when i made this code (a year ago)
ill edit it to use self

By the way when i coded this i just used : for when this function is more important and used . for less important ones, to make it slightly better (as i don’t feel like re-coding this) i replaced module with self in : functions, I’m a better coder now and know that i shouldn’t be using : like that, its not as readable

it’s not that it’s less readable, it’s that it conveys incorrect information to the reader and compiler

1 Like