Hitbox not detecting Characters after they die

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I want my hitbox to detect a character after the target character has died

  1. What is the issue? Include screenshots / videos if possible!

I’m using a custom module inside of StarterCharacterScripts to create the Hitbox.
At the moment my hitbox perfectly detects the characters, until they die, then it doesnt detect the particular character that respawned, every other character can still be hit.
If I reset after the target character dies, I’m able to hit it again, so my immediate guess is that the issue is something to do with the Module not refreshing its character instances.

  1. What solutions have you tried so far? Did you look for solutions on the Creator Hub?

I’ve tried looking around DevForum but I havent found anything clear, I did try to reset the character references by making a function that basically took in the parameters for all the variables I used and then sets them to nil so that the next time the variables are declared, it would be with a fresh set of values (but that in itself is just guesswork)

VIDEO OF BUG: Watch Hitbox Bug | Streamable

Here’s the Hitbox Module script inside of StarterCharacterScripts:

local module = {}

local Pathways = require(game.ReplicatedStorage.Modules.Pathways)

local Debris = game:GetService("Debris")

local players = game:GetService("Players")



local hitSet = {}

local hitPartTable = {}


function module.createHitbox(char, cframe, size, overlapParameters)




	local hitboxResult = workspace:GetPartBoundsInBox(cframe, size, overlapParameters)

	local reference = Instance.new("Part") -- CREATING A PART TO INDICATE THE LOCATION & SIZE OF THE HITBOX

	reference.Parent = workspace
	reference.CFrame = cframe
	reference.Size = size
	reference.CanCollide = false
	reference.Color = Color3.new(1, 0.0470588, 0.0470588)
	reference.Transparency = 0.5
	reference.Anchored = true

	Debris:AddItem(reference, .2)


	if hitboxResult then


		if #hitPartTable > 0 then
			table.clear (hitPartTable) -- DELETING PREVIOUS STORED CHARACTER(S)
		end

		for _, part in (hitboxResult)  do
			if part:IsDescendantOf(char) then 
				_, part = nil -- IF THE PART BELONGS TO THE PLAYER'S CHARACTER THEN IT GETS SET TO NIL
			end



			if part ~= nil then -- MAKING SURE THE PLAYER DOESN'T HIT THEMSELVES

				if part.Name == "Hitbox" then 
					print(part.Parent.Parent)
					local hitTarg = part.Parent.Parent 
					table.insert(hitSet, hitTarg)
					print (hitSet)
				end
				
				for _, targ in hitSet do
					if not table.find(hitPartTable, targ) then
						table.insert(hitPartTable, targ)
					end
					table.clear(hitSet)
				end

			end

		end


		print (hitPartTable) -- CHECKING THAT THE VALUES STILL EXIST IN THE TABLE

		return hitPartTable -- SENDING THE TABLE WITH THE CHARACTER(S) THAT WERE HIT TO THE CLIENT

	end





end




function module.createDotHitbox(char, enemies)

----- MODULE FUNCTION THAT CHECKS THAT THE ENEMY CHARACTER IS WITHIN A CERTAIN RANGE AND VIEW OF THE PLAYER -----


	if char == nil or enemies == nil then return end
	
	local angle = 45 -- MAX VIEW ANGLE
	local distance = 10 -- MAX DISTANCE

	for _, enemy in enemies do
		local resultantVector = enemy.PrimaryPart.Position - char.PrimaryPart.Position -- GETTING THE DISTANCE AND DIRECTION OF THE ENEMY FROM THE PLAYER
		local lookVector = char.PrimaryPart.CFrame.LookVector -- GETTING THE DIRECTION THE PLAYER IS FACING
		local normalResult = resultantVector.Unit -- GETTING THE NORMALIZED DIRECTION
		local magnitude = resultantVector.Magnitude -- GETTING THE DISTANCE

		local Dot = lookVector:Dot(normalResult) -- GETTING THE DOT PRODUCT OF THE PLAYERS LOOKING DIRECTION AND THE DIRECTION OF WHERE THE ENEMY IS
		local radianAngle = math.acos(Dot) -- GETTING ANGLE IN RADIANS
		local degAngle = math.deg(radianAngle) -- CONVERTING RADIANS TO DEGREES

		local inRange = magnitude <= distance 

		local inView = degAngle <= angle

		local canHit = inRange and inView

		if not canHit then 
			warn("You can't hit that.")
			return 
		end

		print(char.Name.." has hit, "..enemy.Name)

		return enemies
	end


end





return module

No errors showing in output btw, just nothing printing at all

Thanks for all the help!

not sure if this would help you but this is my hitbox i use

--!strict
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Players = game:GetService('Players')

--> Player
local Player = Players.LocalPlayer

--> config
local size = Vector3.new(5, 5, 5)
local offset = 2

--> private
local function createRaycastParams(Descendants : {Instance}, FilterType : Enum.RaycastFilterType)
	local params = OverlapParams.new()
	
	params.FilterDescendantsInstances = Descendants
	params.FilterType = FilterType
	
	return params
end

local function debugHitbox(cf : CFrame, size : Vector3)
	local dbHitbox = Instance.new('Part')
	
	dbHitbox.Transparency = 0.5
	dbHitbox.CanCollide = false
	dbHitbox.Anchored = true
	dbHitbox.Color = Color3.new(0.75, 0, 0)
	
	dbHitbox.Size = size
	dbHitbox.CFrame = cf
	
	dbHitbox.Parent = workspace.CurrentCamera
	
	task.delay(0.5, dbHitbox.Destroy, dbHitbox)
end

local function filterPlayers(list : {Instance}) : {Player?}
	if #list == 0 then return {} end
	
	local players = {}
	
	for _, v in ipairs(list) do
		local character = v:FindFirstAncestorWhichIsA('Model')
		if not character then continue end
		
		local humanoid = character:FindFirstChildWhichIsA('Humanoid')
		if not humanoid then continue end
		if humanoid.Health <= 0 then continue end
		
		local plr = Players:GetPlayerFromCharacter(character)
		if not plr then continue end
		
		if table.find(players, plr) then continue end
		
		table.insert(players, plr)
	end
	
	return players
end

--> Service
local HitboxService = {}

--> Public
function HitboxService.Cast() : {Player?}
	local character = Player.Character
	if not character then return {} end
	
	local hitboxCFrame = character.PrimaryPart.CFrame * CFrame.new(0, 0, -offset)
	
	-- debugHitbox(hitboxCFrame, size)
	
	local characters = {}
	
	for _, v in ipairs(Players:GetPlayers()) do
		local char = v.Character
		if char and char ~= character then
			table.insert(characters, char)
		end
	end
	
	local params = createRaycastParams(characters, Enum.RaycastFilterType.Include)
	
	local result = workspace:GetPartBoundsInBox(hitboxCFrame, size, params)
	local playersHit = filterPlayers(result)
	
	return playersHit
end

--> return
return HitboxService
1 Like

Thanks alot, I added it into StarterCharacterScripts with a few tweaks to detect characters that dont have players behind them (NPCS) and now even after the character dies it still detects them.

I’ll look more into the differences between my script and the one you provided incase anyone needs a definitive solution

Alright so explanation of the solution, or at least what I changed to achieve the same result as x6’s script:

  1. I had a bunch of parameters being passed into the module from the client rather than defining each variable as it was needed in the module itself.

  2. I had a broken structure where I was executing a lot of functions on the local script and passing variables along from each of them through the local script. Instead they could have been merged into 1 module function.

  3. I was creating the Hitbox by calling the module function on the client.

Pretty much all the potential causes (I can think of) have to do with passing too much data around where it could have been simplified.

Hopefully, this has helped you to understand potential solutions for anyone seeing this later.

Thanks a lot for the help :folded_hands: @ossuarys

2 Likes

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