HitBox driving me up the wall

Okay so i’m trying to create this hitbox for my battlegrounds game and it’s about to make me crash out

local RunServ = game:GetService("RunService")

local GroundedHitBox = {}

GroundedHitBox.__index = GroundedHitBox

function GroundedHitBox.NewHitBox(Size, Cframe, Shape, Life, Attach)
	local Self = setmetatable({}, GroundedHitBox)
	Self.Size = Size or Vector3.new(0,0,0)
	Self.CFrame = Cframe or CFrame.new(0,0,0)
	Self.Attach = Attach
	Self.Life = Life
	Self.Shape = Shape or Enum.PartType.Block
	Self.Visualizer = true
	Self.Connection = true
	Self.Touched = nil
	return Self
end



function GroundedHitBox:Visualize()
	if not self.Visualizer then return end
		local Part = Instance.new("Part")
		Part.Name = "HitBox"
		Part.Size = self.Size
		Part.CFrame = self.CFrame
		Part.Shape = self.Shape 
		Part.Anchored = true
		Part.CanCollide = false
		Part.Transparency = 0.5
		Part.BrickColor = BrickColor.new("Bright red")
		Part.Parent = workspace
		self.Visualizer = Part
		
		self.Connection = RunServ.Heartbeat:Connect(function()
			if self.Attach then
			self.Visualizer.CFrame = self.Attach.CFrame
			end
		end)
		
		task.delay(self.Life, function()
			self.Visualizer:Destroy()
		end)
		
		self.Visualizer.Touched:Connect(function()
			self.Touched = self.Visualizer.Touched
		end)
		
end

function GroundedHitBox:Create()
	task.spawn(function()
		self:Visualize()
	end)
end

function GroundedHitBox:Destroy()
	self.setmetatable(self,nil)
end

return GroundedHitBox
e

I can’t figure out how to make it to where i can use the touched event or something to check when any humanoid comes in contact with it

local RP = game:GetService("ReplicatedStorage")
local SS = game:GetService("ServerStorage")
local Modules = RP.Modules
local Module2 = SS.Modules

local StunHandler = require(Module2.StunHandlerV2)
local HitService = require(Module2.HitService)
local GroundedHitBox = require(Module2.GroundedHitBox)
local RagdollMOD = require(RP.Modules.Ragdoll)
local VariableCheckMOD = require(RP.Modules.ValueCheck)
local VariableMOD = require(RP.Modules.ValueModule)

local WalkSpeed = 30
local JumpHeight = 7.2

local module = {}

local function changecombo(Character)
	local Values = Character:WaitForChild("PlayerValues")
	local Combo = Values:WaitForChild("Combo")

	if Combo.Value < 4 then
		Combo.Value += 1
	elseif Combo.Value >= 4 then
		Combo.Value = 1
	end
end

--local function ComboReset(Character, OldCombo)
--	task.delay(1, function()
--		local Values = Character:WaitForChild("PlayerValues")
--		local Current = Values:FindFirstChild("Combo")

--		if OldCombo.Value == 4 then return end

--		if Current.Value == OldCombo.Value and Values:FindFirstChild("Attacking").Value == false then
--			Current.Value = 1
--		end
--	end)
--end


function module:Start(Character, HoldingSpace)
	if not VariableCheckMOD:CombatCheck(Character) then return end

	local Humanoid = Character:WaitForChild("Humanoid")
	local Animator = Humanoid:WaitForChild("Animator")
	local Hrp = Character:WaitForChild("HumanoidRootPart")
	local Values = Character:FindFirstChild("PlayerValues")
	local Combo = Values:FindFirstChild("Combo")

	local Attacking = Values:FindFirstChild("Attacking")
	local Animations = RP.AnimationFolder[script.Parent.Name].CombatAnimations:GetChildren()
	local Animation = Animator:LoadAnimation(Animations[Combo.Value])
	local HitBox = GroundedHitBox.NewHitBox(Vector3.new(5,5,5),CFrame.new(0,0,-2.5),Enum.PartType.Block,0.4,Hrp)
	
	HitBox:Create()
	
	if HitBox.Touched then
		local hum = HitBox.Parent:FindFirstChild("Humanoid")
		
		
		if hum.Parent == Humanoid then return end
		
		if hum then
			if Combo == 4 then
				HitService.Hit(hum,1.5,0.3,Hrp.CFrame.LookVector*10,nil)
			else
				HitService.Hit(hum,1,0.3,Hrp.CFrame.LookVector*5,nil)
			end
		end
	end
	

	Animation:Play()
	Humanoid.WalkSpeed = 15
	Humanoid.JumpHeight = 0
	Attacking.Value = true

	if Combo.Value == 4 then
		Humanoid.WalkSpeed = 0
		Humanoid.JumpHeight = 0
	end

	Animation.Stopped:Connect(function()
		changecombo(Character)
		task.delay(0.12,function()
			Attacking.Value = false  
			Humanoid.WalkSpeed = WalkSpeed  
			Humanoid.JumpHeight = JumpHeight	
		end)
	end)
	
end


return module

So you’re only checking if HitBox.Touched is fired within the module:Start function?
So if the module is called the Touched event has to happen at precisely the same time as when the function is called for the script to work.

Sounds like you may want to have the HitBox already welded to the player and just enable its CanTouch Property during battle which would probably be quicker than recreating it every time.
Because you need this to fire exactly when the Touched event works you should have the Touched function fire the function instead then check all the other parameters to see if the Touch is valid.

I don’t really know how metatables work but this can be made a lot simpler. Just use a loop of any kind over the duration of how long you want the hitbox to be hitting. Then, use any detection method like spacial queries or magnitude instead of .Touched().

Okay i’m still having trouble and if i’m being honest i’m just shooting in the dark i’m lost

local RunServ = game:GetService("RunService")

local GroundedHitBox = {}

GroundedHitBox.__index = GroundedHitBox

function GroundedHitBox.NewHitBox(Size, Cframe, Shape, Life, Attach,OverLap)
	local Self = setmetatable({}, GroundedHitBox)
	Self.Size = Size or Vector3.new(0,0,0)
	Self.CFrame = Cframe or CFrame.new(0,0,0)
	Self.Attach = Attach
	Self.Life = Life
	Self.Shape = Shape or Enum.PartType.Block
	Self.Visualizer = true
	Self.Connection = true
	Self.Param = OverlapParams.new()
	Self.Param.FilterDescendantsInstances = {Self}
	Self.Parts = {}
	return Self
end

function GroundedHitBox:Visualize()
	if not self.Visualizer then return end
	local Part = Instance.new("Part")
	Part.Name = "HitBox"
	Part.Size = self.Size
	Part.CFrame = self.CFrame
	Part.Shape = self.Shape 
	Part.Anchored = true
	Part.CanCollide = false
	Part.Transparency = 0.5
	Part.BrickColor = BrickColor.new("Bright red")
	Part.Parent = workspace
	self.Visualizer = Part

	self.Connection = RunServ.Heartbeat:Connect(function()
		if self.Attach then
			self.Visualizer.CFrame = self.Attach.CFrame
		end
	end)

	task.delay(self.Life, function()
		self.Visualizer:Destroy()
	end)

	while true do

		local Hit = {}

		for i,v in pairs(self.Parts) do
			if v.Parent:FindFirstChildOfClass("Humanoid") and not table.find(table, v.Parent) then
				table.insert(Hit, v.Parent)
			end
		end
		self.Param:AddToFilter(Hit)

		task.wait()
	end

end

function GroundedHitBox:Create()
	task.spawn(function()
		self:Visualize()
	end)
end

function GroundedHitBox:Destroy()
	self.setmetatable(self,nil)
end

return GroundedHitBox


I don’t really know how to make it to where the hitbox does it’s just and detects when theres another humanoid the hitbox appears but it just doesn’t make them take damage

local RP = game:GetService("ReplicatedStorage")
local SS = game:GetService("ServerStorage")
local Modules = RP.Modules
local Module2 = SS.Modules

local StunHandler = require(Module2.StunHandlerV2)
local HitService = require(Module2.HitService)
local GroundedHitBox = require(Module2.GroundedHitBox)
local RagdollMOD = require(RP.Modules.Ragdoll)
local VariableCheckMOD = require(RP.Modules.ValueCheck)
local VariableMOD = require(RP.Modules.ValueModule)

local WalkSpeed = 30
local JumpHeight = 7.2

local module = {}

local function changecombo(Character)
	local Values = Character:WaitForChild("PlayerValues")
	local Combo = Values:WaitForChild("Combo")

	if Combo.Value < 4 then
		Combo.Value += 1
	elseif Combo.Value >= 4 then
		Combo.Value = 1
	end
end

--local function ComboReset(Character, OldCombo)
--	task.delay(1, function()
--		local Values = Character:WaitForChild("PlayerValues")
--		local Current = Values:FindFirstChild("Combo")

--		if OldCombo.Value == 4 then return end

--		if Current.Value == OldCombo.Value and Values:FindFirstChild("Attacking").Value == false then
--			Current.Value = 1
--		end
--	end)
--end


function module:Start(Character, HoldingSpace)
	if not VariableCheckMOD:CombatCheck(Character) then return end

	local Humanoid = Character:WaitForChild("Humanoid")
	local Animator = Humanoid:WaitForChild("Animator")
	local Hrp = Character:WaitForChild("HumanoidRootPart")
	local Values = Character:FindFirstChild("PlayerValues")
	local Combo = Values:FindFirstChild("Combo")

	local Attacking = Values:FindFirstChild("Attacking")
	local Animations = RP.AnimationFolder[script.Parent.Name].CombatAnimations:GetChildren()
	local Animation = Animator:LoadAnimation(Animations[Combo.Value])
	local HitBox = GroundedHitBox.NewHitBox(Vector3.new(5,5,5),CFrame.new(0,0,-2.5),Enum.PartType.Block,0.4,Hrp)
	
	HitBox:Create()
	
	for i,v in pairs(HitBox.Parts) do
		if v:FindFirstChildOfClass("Humanoid") and not Humanoid then
			HitService.Hit(v,1,0.2,Hrp.CFrame.LookVector*10,nil)
		end
	end
	

	Animation:Play()
	Humanoid.WalkSpeed = 15
	Humanoid.JumpHeight = 0
	Attacking.Value = true

	if Combo.Value == 4 then
		Humanoid.WalkSpeed = 0
		Humanoid.JumpHeight = 0
	end

	Animation.Stopped:Connect(function()
		changecombo(Character)
		task.delay(0.12,function()
			Attacking.Value = false  
			Humanoid.WalkSpeed = WalkSpeed  
			Humanoid.JumpHeight = JumpHeight	
		end)
	end)
	
end


return module

After 5 hours i finally fixed it by myself. Thanks :+1:

I’ll also figure out myself how to make it to where the damage is consistent and not random

Please post how you fixed it so other people with the same issue who search the forum might get help from your posts.

I also found out the issue :skull:

local HitHuman = {}
	
	local function OnHit(Part)
		local HitCharacter = Part.Parent
			if HitCharacter and HitCharacter ~= Character then
				local HUM = HitCharacter:FindFirstChild("Humanoid")
				
				if HUM and not HitHuman[HUM] then
					HitHuman[HUM] = true
				if Combo.Value >= Settings.MaxCombo then
					Settings.Damage = 1.5
					Settings.KnockBack = 1000
				elseif Combo.Value <= Settings.MaxCombo then
					Settings.Damage = 1
					Settings.KnockBack = 1
				end
				
				if HUM.Health > 0 then
					HitService.Hit(HUM,Settings.Damage,0.4,Hrp.CFrame.LookVector* Settings.KnockBack, nil)
				else
					return
				end
			end
		end
	end
			

	
	for i,v in pairs(workspace:GetPartsInPart(HitBox)) do
		if v:IsA("Part") then
			OnHit(v)
		end
	end

It was because i didn’t state the value for the combo so it the module script didn’t know what to do when getting to that line

local RunServ = game:GetService("RunService")

local GroundedHitBox = {}


function GroundedHitBox.NewHitBox(Size, Cframe, Shape, Life, Attach,Parent)
	local Self = Instance.new("Part")
	Self.Parent = Parent
	local Attachment = Instance.new("Weld")
	Attachment.Parent = Self
	Self.Size = Size or Vector3.new(0,0,0)
	Self.CFrame = Cframe or CFrame.new(0,0,0)
	Self.Anchored = false
	Self.CanCollide = false
	Self.Transparency = 0.5
	Self.Shape = Shape or Enum.PartType.Block
	Attachment.Part0 = Attach
	Attachment.Part1 = Self
	
	local Lap = OverlapParams.new()
	Lap.FilterDescendantsInstances = {Self}
	Lap.FilterType = Enum.RaycastFilterType.Exclude
	
	local Parts = {}
	local StartTime = tick()
	
	local function Detect()
		local Parts = workspace:GetPartsInPart(Self, Lap)
		for i,v in pairs(Parts) do
			if not table.find(Parts, v.Parent) then
				table.insert(Parts, v.Parent)
			end
		end
	end
	
	local Connection
	Connection = RunServ.Heartbeat:Connect(function()
		if tick() - StartTime >= Life then
			Connection:Disconnect()
			Self:Destroy()
		else
			Detect()
		end
	end)
	
	return Self
end

return GroundedHitBox

Also i just looked up a tutorial on youtube
And then just fiddled around took the runservice heartbeat and used that instead of while true cause it legit crashed my roblox studio doing that. Whoops :sob:

1 Like

Atleast i’m able to continue working on my battlegrounds game combat :grin: :+1: all i wanna do is just make something cool and fun for just me and my friends to just hangout and play in