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
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
Atleast i’m able to continue working on my battlegrounds game combat all i wanna do is just make something cool and fun for just me and my friends to just hangout and play in