Figuring out how to stop hitbox when I want to stop it

Hi,

I am trying to figure out how to enable hitbox and disable hitbox when I want to inside a function that uses task.wait(). It’s kind of hard to explain but the problem is when I start the hitbox, I can’t add a task.wait() to stop it because I have another task.wait() cooldown. I don’t want to add task.wait() because it will make the cooldown longer.

Here’s what I mean:

local Client = {}
Client.__index = Client

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService('RunService')

local ContextActionService = require(ReplicatedStorage.Source.Modules.ContextActionUtility)
local RaycastHitbox = require(ReplicatedStorage.Source.Modules.RaycastHitboxV4)

local PlaceHolderDebounce = false

local function PlaySound(Sound, Root)
	local soundClone = Sound:Clone()
	soundClone.Parent = Root
	soundClone:Play()

	game.Debris:AddItem(soundClone,3)
end

function Client.new(Character: Model, Animations: any)
	local self = setmetatable({},Client)
	
	self.Character = Character
	self.Humanoid = Character:WaitForChild("Humanoid")
	self.Root = Character:WaitForChild("HumanoidRootPart")
	self.Tool = self.Character:WaitForChild(script.Parent.Name)
	
	self.Animations = Animations
	self.Hitbox = RaycastHitbox.new(self.Tool.Handle)
	self.Hitbox.Visualizer = true
	
	self.Settings = require(script.Parent.Settings)
	self.LoadedAnimations = {}
	self.Sounds = game:GetService("SoundService")[script.Parent.Name]
	
	self._combo = 1
	self._lastClicked = tick()
	
	for _, anim in pairs(self.Animations:GetChildren()) do 
		self.LoadedAnimations[anim.Name] =  self.Humanoid.Animator:LoadAnimation(anim)
		self.LoadedAnimations[anim.Name].Priority = Enum.AnimationPriority.Action3 -- highest priority
	end
	
	self.Slashing = self.Humanoid:GetAttribute("Slashing")
	self:Equip()
	
	Players.LocalPlayer.CharacterAdded:Connect(function()
		self:Equip()
	end)
	
	local function Attack(Action, InputState, InputType)
		self:M1(Action,InputState,InputType)
	end
	
	ContextActionService:SetImage("M1", "rbxassetid://16141238562")
	ContextActionService:SetSlotPosition("M1", 1)
	ContextActionService:SetImage("M1", "rbxassetid://16141238562")
	ContextActionService:BindAction("M1", Attack, true, Enum.UserInputType.MouseButton1)
	
	return self
end

function Client:Equip()
	self.LoadedAnimations.Equip:Play()
	self.LoadedAnimations.Idle:Play()
	
	PlaySound(self.Sounds["Equip"],self.Root)
end

function Client:M1(Action, InputState, InputType)
	if InputState ~= Enum.UserInputState.Begin then
		return
	end
	
	if not PlaceHolderDebounce then
		PlaceHolderDebounce = true

		print(self.Humanoid:GetAttributes())

		local attackString = "Attack"..tostring(self._combo)

		if tick() - self._lastClicked >= self.Settings["COMBO_RESET"] then
			print("Combo Reset")
			self._combo = 1
		end

		self._lastClicked = tick() 

		self.LoadedAnimations[attackString]:Play()
		
		self.Hitbox:HitStart() -- start hitbox
		
		PlaySound(self.Sounds["M1"],self.Root)

		task.wait(self.Settings["M1_COOLDOWN"])
		
		self.Hitbox:HitStop() -- stop hitbox
		
		if self._combo < self.Settings.COMBOS then
			self._combo += 1
		else
			self._combo = 1
		end

		PlaceHolderDebounce = false
	end
end

return Client

Adding a task.wait():

local Client = {}
Client.__index = Client

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService('RunService')

local ContextActionService = require(ReplicatedStorage.Source.Modules.ContextActionUtility)
local RaycastHitbox = require(ReplicatedStorage.Source.Modules.RaycastHitboxV4)

local PlaceHolderDebounce = false

local function PlaySound(Sound, Root)
	local soundClone = Sound:Clone()
	soundClone.Parent = Root
	soundClone:Play()

	game.Debris:AddItem(soundClone,3)
end

function Client.new(Character: Model, Animations: any)
	local self = setmetatable({},Client)
	
	self.Character = Character
	self.Humanoid = Character:WaitForChild("Humanoid")
	self.Root = Character:WaitForChild("HumanoidRootPart")
	self.Tool = self.Character:WaitForChild(script.Parent.Name)
	
	self.Animations = Animations
	self.Hitbox = RaycastHitbox.new(self.Tool.Handle)
	self.Hitbox.Visualizer = true
	
	self.Settings = require(script.Parent.Settings)
	self.LoadedAnimations = {}
	self.Sounds = game:GetService("SoundService")[script.Parent.Name]
	
	self._combo = 1
	self._lastClicked = tick()
	
	for _, anim in pairs(self.Animations:GetChildren()) do 
		self.LoadedAnimations[anim.Name] =  self.Humanoid.Animator:LoadAnimation(anim)
		self.LoadedAnimations[anim.Name].Priority = Enum.AnimationPriority.Action3 -- highest priority
	end
	
	self.Slashing = self.Humanoid:GetAttribute("Slashing")
	self:Equip()
	
	Players.LocalPlayer.CharacterAdded:Connect(function()
		self:Equip()
	end)
	
	local function Attack(Action, InputState, InputType)
		self:M1(Action,InputState,InputType)
	end
	
	ContextActionService:SetImage("M1", "rbxassetid://16141238562")
	ContextActionService:SetSlotPosition("M1", 1)
	ContextActionService:SetImage("M1", "rbxassetid://16141238562")
	ContextActionService:BindAction("M1", Attack, true, Enum.UserInputType.MouseButton1)
	
	return self
end

function Client:Equip()
	self.LoadedAnimations.Equip:Play()
	self.LoadedAnimations.Idle:Play()
	
	PlaySound(self.Sounds["Equip"],self.Root)
end

function Client:M1(Action, InputState, InputType)
	if InputState ~= Enum.UserInputState.Begin then
		return
	end
	
	if not PlaceHolderDebounce then
		PlaceHolderDebounce = true

		print(self.Humanoid:GetAttributes())

		local attackString = "Attack"..tostring(self._combo)

		if tick() - self._lastClicked >= self.Settings["COMBO_RESET"] then
			print("Combo Reset")
			self._combo = 1
		end

		self._lastClicked = tick() 

		self.LoadedAnimations[attackString]:Play()
		
		PlaySound(self.Sounds["M1"],self.Root)
		self.Hitbox:HitStart() -- start hitbox
		
		task.wait(0.4)
		
		self.Hitbox:HitStop() -- stop hitbox

		task.wait(self.Settings["M1_COOLDOWN"])

		
		if self._combo < self.Settings.COMBOS then
			self._combo += 1
		else
			self._combo = 1
		end

		PlaceHolderDebounce = false
	end
end

return Client

So my question is, how do I add a task.wait() behind the scenes that doesn’t interfere with the M1_COOLDOWN?

Without looking at the code. You could always have the some things running as a sup task that end up more or less on their own timers. As they are executed and the script keeps moving. Not even sure if this fits with what you’re doing however. (just an example)

task.spawn(function() FireWorks(4) end)

Will run this function as a sup function. While still continuing. Then it’s just a matter of timing everything out. You can also commutate via variables with/from the sub branches.

1 Like

I’m not exactly too sure what are your needs regarding this, but there are a couple of ways you can make a part of your script yield without interfering with the rest of the tasks:

You can make two scripts instead of one
-- First script
function MyCooldown()
	task.wait(5)
	print("Cooldown ended!")
end

MyCooldown()
-- Second script
local RunService = game:GetService("RunService")

function MyTaskWithoutACooldown()
	print("This prints every frame!")
end
RunService.Heartbeat:Connect(MyTaskWithoutACooldown)
You can use a coroutine

The documentation for coroutines can be found here

local MyCooldown = coroutine.wrap(function()
	task.wait(5)
	print("Cooldown ended!")
end)

-- This should stop the entire code but with coroutines it doesn't
MyCooldown()

print("This prints inmediately!")
You can use a timer along with a variable

This method is trickier to use and I wouldn’t recommend it for most use cases but it might just fit your needs

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local inCooldown = false

function MyTask()
	print("Task done!")
	inCooldown = true
end

local timer = 0
RunService.Heartbeat:Connect(function(deltaTime: number)
	if inCooldown == true then
		timer += deltaTime
	end
	if timer > 5 then
		inCooldown = false
	end
end)

-- Fires whenever the user presses anything on their mouse or keyboard
UserInputService.InputBegan:Connect(function()
	if inCooldown == true then
		print("Still in cooldown!")
	else
		timer = 0
		MyTask()
	end
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.