Help with hitboxes

So recently, I finished a local script handling the animations, and giving the player the velocity whenever they use a m1, or m2 of a move.
i’m not sure how to make the hitbox activating it and deactivating it whenever I want. i’ll send gyazo gifs of the animations
I looked around for youtube videos, but they don’t match my criteria. I want the m2 to have multiple times, similar to Rogue Lineage, so i’m thinking of GetMarkerReachedSignal,
M1 ANIMATION: https://gyazo.com/802a0102ea3b395ac544e7812e7ae9c7
M2 ANIMATION: https://gyazo.com/88a76290a4c29c3d9e2bd5d42e4b3c1d
LOCAL

local Remotes = game.ReplicatedStorage.Remotes
local M1Event = Remotes.M1
local M2Event = Remotes.M2
local Player = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local character =Player.Character or Player.CharacterAdded:wait()
local Cooldown = Instance.new("BoolValue", game.Players.LocalPlayer)
Cooldown.Value = false
local Humanoid = character:WaitForChild("Humanoid")
local animator = Humanoid:FindFirstChildOfClass("Animator")
local Mouse = Player:GetMouse()
local m1 = Instance.new("Animation")
local Debounce = false
local BV 
local BV2 
local DebounceTimer = 6
m1.AnimationId = "rbxassetid://5945839988"
local m2 = Instance.new("Animation")
m2.AnimationId = "rbxassetid://5949219966"
	local animationTrack = animator:LoadAnimation(m2)
	local lolanimation = animator:LoadAnimation(m1)
local canMove
local model = character.HumanoidRootPart
local speed = 0.25
local function thread1()
	if canMove == true then
		repeat
			BV2.MaxForce = Vector3.new(1,1,1) * math.huge
			BV2.Velocity = Player.Character.HumanoidRootPart.CFrame.LookVector * 16
			wait()
			game:GetService("RunService").Heartbeat:Wait()
		until canMove == false
	end
end
local function thread()
	if canMove == true then
		repeat
			BV.MaxForce = Vector3.new(1,1,1) * math.huge
			BV.Velocity = Player.Character.HumanoidRootPart.CFrame.LookVector * 13
			wait()
			game:GetService("RunService").Heartbeat:Wait()
		until canMove == false
	end
end
local tool = script.Parent.Parent.DemonFlip
local mouse = Player:GetMouse()
mouse.Button1Down:Connect(function()
	if character:FindFirstChild("DemonFlip") and Cooldown.Value == false then
		Cooldown.Value = true
		BV = Instance.new("BodyVelocity", character.HumanoidRootPart)
		local sound = Instance.new("Sound", game.Players.LocalPlayer)
		sound.SoundId = "rbxassetid://5355789788"
			Humanoid.WalkSpeed = 0
			sound:Play()
		lolanimation:Play()
		M1Event:FireServer()
		canMove = true
spawn(thread)		
				lolanimation.Stopped:wait()
				Humanoid.WalkSpeed = 16
				canMove = false
		sound:Destroy()
		BV:Destroy()
		BV = nil
	end
		end)


	
mouse.Button2Down:Connect(function()
		if character:FindFirstChild("DemonFlip") and Cooldown.Value == false then
		Cooldown.Value = true
		BV2 = Instance.new("BodyVelocity", character.HumanoidRootPart)
		local sound = Instance.new("Sound", game.Players.LocalPlayer)
		sound.SoundId = "rbxassetid://5355789788"
		sound:Play()
		animationTrack:AdjustSpeed(1.5)
		animationTrack:Play()
		animationTrack:AdjustSpeed(1.5)
		M2Event:FireServer()
		Humanoid.WalkSpeed = 0
		canMove = true
		spawn(thread1)
		animationTrack.Stopped:wait()
		canMove = false
		BV2:Destroy()
		BV2 = nil
		animationTrack:AdjustSpeed(1)
		Humanoid.WalkSpeed = 16
		sound:Destroy()
		end
end)
Cooldown.Changed:Connect(function()
	if Cooldown.Value == true then
		wait(5)
		Cooldown.Value = false
	end
		end)

SERVER

local remotes = game.ReplicatedStorage.Remotes
local M1Event = remotes.M1
local M2Event = remotes.M2

M1Event.OnServerEvent:Connect(function()
	
end)

M2Event.OnServerEvent:Connect(function()

end)
-------Dont know what to do-----------

(Yes there is some unnecessary variables, that is because I forgot to remove them while I was changing how the cooldown worked)

2 Likes

Is anyone able to help? It’s been 2 days

Here’s a list of research on what to do for hitboxes which has been compiled very nicely by @HappyLemonzYT.

Personally I suggest using RotatedRegion3 because of the fact you can rotate the region3 and create a region easier using BaseParts which can lead to easier debugging. The information you send on the remote should only the position on where create the hitbox and it should be sent during the GetMarkerReachedSignal on the client because of animation syncing issues with the server from what I have seen, the rest like damage and size can be handled on the server through a dictionary combo system like for the last frames there will be a large hitbox that deals a lot of damage and such.

2 Likes

I not sure exactly how you have it all setup but if you are wanting a hitbox to only be active for a few seconds you can setup something like this which i have tested in the past

on this you make a connection when they click the mouse for about half a second or until it hits another player then disable the connection until the next click

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:WaitForChild('HumanoidRootPart')
local Mouse = Player:GetMouse()

local Connection1

Mouse.Button1Down:Connect(function()
	-- animate
	Connection1 = Hitboxpart.Touched:Connect(function(hit)  -- make a connection each time but disconnect when attack is over or they hit someone
		local HitPlayer = game.Players:GetPlayerFromCharacter(hit.Parent)
		if HitPlayer and Player ~= HitPlayer then
			
			Connection1:Disconnect()  -- disconnects the connection if it hit someone  
		end
	end)
	wait(.5)  -- the amount of time you want to wait before disabling the touch connection 
	Connection1:Disconnect()  -- disconnects the connection if it hit someone  
end)

or you could leave a connection to the hitblock but only let it go through if they are in say a attack/click

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:WaitForChild('HumanoidRootPart')
local Mouse = Player:GetMouse()

local Connection1
local Attacking
Mouse.Button1Down:Connect(function()
	-- animate
	if Attacking then return end  -- already attacking don't do it again
	Attacking = true
	wait(.5)
	Attacking = false
end)

Hitboxpart.Touched:Connect(function(hit)  -- makes and leaves a live connection 
	if not Attacking then return end  -- if they are not active attacking it will just ignore anything it hits
	local HitPlayer = game.Players:GetPlayerFromCharacter(hit.Parent)
	if HitPlayer and Player ~= HitPlayer then
		Attacking = false  -- they hit a player so stop the hit detection until next attack  
	end
end)

you can do this many ways but these are 2 examples this would of course need edited and add some debounces to the attacks or change attack delays

can I get some help with region3? I found a rotated region3 module,
Rotated Region 3 Module but I have not worked on hitboxes in my time of developing so I need some more help

Have you experimented with it? First, you CFrame a part that represents the hitbox to where you want it then you check the parts within the region and if they belong to a character like raycasting.

local part --whatever you CFrame it to
local hitboxRegion = RotatedRegion3.FromPart(part) --create hitbox
local partsInRegion = hitboxRegion:FindPartsInRegion3WithIgnoreList(Instance Array ignore, Integer maxParts)

for _,part in pairs(partsInRegion) do

--check if the part belongs to the character via part .Parent
local character = part.Parent
local humanoid = character:FindFirstChild("Humanoid")

if humanoid then
--damage them lol
end

end

Would this work?

local remotes = game.ReplicatedStorage.Remotes
local M1Event = remotes.M1
local M2Event = remotes.M2

M1Event.OnServerEvent:Connect(function()
	
end)

M2Event.OnServerEvent:Connect(function()
	local part = Player.Character["Right Leg"]
	part.Anchored = false
	part.CanCollide = false
        part.Transparency = 1
	local hitboxRegion = RotatedRegion3.FromPart(part) --create hitbox
	local partsInRegion = hitboxRegion:FindPartsInRegion3WithIgnoreList(Instance Array ignore, Integer maxParts)

	for _,part in pairs(partsInRegion) do

		local character = part.Parent
		local humanoid = character:FindFirstChild("Humanoid")

		if humanoid then
			humanoid:TakeDamage(10)
		end

	end

	end)

EDIT: fixed some syntax errors.

I get an error from this script.image

So i’ve completely changed the script,

local remotes = game.ReplicatedStorage.Remotes
local M1Event = remotes.M1
local M2Event = remotes.M2
local canAttack = false
M1Event.OnServerEvent:Connect(function()
	
end)
M2Event.OnServerEvent:Connect(function(playerWhoFired)
	local part = game.ReplicatedStorage.HitBox:Clone()
	part.Parent = playerWhoFired.Character["Right Leg"]
	part.CFrame = playerWhoFired.Character['Right Leg'].CFrame * CFrame.new(0,-1.3,0)
	local Weld = Instance.new("WeldConstraint", playerWhoFired.Character["Right Leg"])
	Weld.Part0 = playerWhoFired.Character["Right Arm"]
	Weld.Part1 = part
	part.Anchored = false
	part.CanCollide = false
	part.Transparency = 1
	canAttack = true
	local function removeattack()
		wait(1)
		canAttack = false
		part:Destroy()
		Weld:Destroy()
	end
spawn(removeattack)
	part.Touched:Connect(function(hit)
		if hit.Parent ~= playerWhoFired then
			local character = hit.Parent
			local humanoid = character:FindFirstChild("Humanoid")
			if humanoid then
				humanoid:TakeDamage(3)
			end

		end

	end)
	end)

resulting in no errors, and the script working. One last question for the developer forum. How would I disable and enable the hitbox when a getmarkerreachedsignal is hit within the server script? I have never worked with animations in serverscripts, as I do them in localscripts.

I cannot tell from your script which line is 17.
Can you indicate it contents please.

This is a hitbox script which makes a hitbox in the right leg, but it activates at the start of the animation. So I want to handle the animation in a serverscript and use a getmarkerreachedsignal to activate and deactivate it.

The message implies a syntax error so which line is line 17?

(3 0 caraaaaaaaaaaaaaaaactersss)

The animation does play from the server, problem is it’s not dealing damage

local remotes = game.ReplicatedStorage.Remotes
local M1Event = remotes.M1
local M2Event = remotes.M2
local canAttack = false
local animation = script.Animation



M1Event.OnServerEvent:Connect(function()
	
end)
M2Event.OnServerEvent:Connect(function(playerWhoFired)
	local part = game.ReplicatedStorage.HitBox:Clone()
	part.Parent = playerWhoFired.Character["Left Leg"]
	part.CFrame = playerWhoFired.Character['Left Leg'].CFrame * CFrame.new(0,-1.3,0)
	local Weld = Instance.new("WeldConstraint", playerWhoFired.Character["Right Leg"])
	Weld.Part0 = playerWhoFired.Character["Left Leg"]
	Weld.Part1 = part
	part.Anchored = false
	part.CanCollide = false
	part.Transparency = 1
	local function playAnimationFromServer(character, animation)
		local Humanoid = playerWhoFired.Character:FindFirstChildOfClass("Humanoid")
		if Humanoid then
			local animation = script.Animation
			local animator = Humanoid:FindFirstChildOfClass("Animator")
			if animator then
				local animationTrack = animator:LoadAnimation(animation)
				animationTrack:Play()
				animationTrack:AdjustSpeed(1.5)
				animationTrack:GetMarkerReachedSignal("attack"):Connect(function()
					canAttack = true 
					wait(0.2)
					canAttack = false
					wait(1.4)
					Weld:Destroy()
					part:Destroy()
			end)
			end
		end
	end
	

	playAnimationFromServer()
	local function removeattack()
		wait(1)
		canAttack = false
		part:Destroy()
		Weld:Destroy()
	end
	part.Touched:Connect(function(hit)
		if hit.Parent ~= playerWhoFired and canAttack == true then
			local character = hit.Parent
			local humanoid = character:FindFirstChild("Humanoid")
			if humanoid then
				humanoid:TakeDamage(3)
			end
		end
	end)
end)







		


Nevermind! It was a small misspelling. Heres the full code

local remotes = game.ReplicatedStorage.Remotes
local M1Event = remotes.M1
local M2Event = remotes.M2
local canAttack = false
local animation = script.Animation



M1Event.OnServerEvent:Connect(function()
	
end)
M2Event.OnServerEvent:Connect(function(playerWhoFired)
	local part = game.ReplicatedStorage.HitBox:Clone()
	part.Parent = playerWhoFired.Character["Left Leg"]
	part.CFrame = playerWhoFired.Character['Left Leg'].CFrame * CFrame.new(0,-1.3,0)
	local Weld = Instance.new("WeldConstraint", playerWhoFired.Character["Right Leg"])
	Weld.Part0 = playerWhoFired.Character["Left Leg"]
	Weld.Part1 = part
	part.Anchored = false
	part.CanCollide = false
	part.Transparency = 1
	local function playAnimationFromServer(character, animation)
		local Humanoid = playerWhoFired.Character:FindFirstChildOfClass("Humanoid")
		if Humanoid then
			local animation = script.Animation
			local animator = Humanoid:FindFirstChildOfClass("Animator")
			if animator then
				local animationTrack = animator:LoadAnimation(animation)
				animationTrack:Play()
				animationTrack:AdjustSpeed(1.5)
				animationTrack:GetMarkerReachedSignal("Attack"):Connect(function()
					print("hello")
					canAttack = true 
					wait(0.2)
					canAttack = false
					wait(1.4)
					Weld:Destroy()
					part:Destroy()
			end)
			end
		end
	end
	

	playAnimationFromServer()
	local function removeattack()
		wait(1)
		canAttack = false
		part:Destroy()
		Weld:Destroy()
	end
	part.Touched:Connect(function(hit)
		if hit.Parent ~= playerWhoFired and canAttack == true then
			print("yo")
			canAttack = false
			local character = hit.Parent
			local humanoid = character:FindFirstChild("Humanoid")
			if humanoid then
				humanoid:TakeDamage(3)
			end
		end
	end)
end)
1 Like