Nearby players detector not working

I made a nearby player detectore with a hitbox that adds them into a table if they touched the table and remove them when the touch ended. But when I tried it with 2 players, instead of removing only 1 player, it removed all the players in the table, and when the first position in the table ended the touch and go back, it only prints the name of that player

Script
local BValue = script.Parent:FindFirstChild("isAttacking")
local Hitbox = script.Parent:FindFirstChild("Hitbox")

local nearbyPlayers = {}

Hitbox.Touched:Connect(function(Part)
	if BValue.Value == true then
		if Part.Parent:FindFirstChild("Humanoid") and game.Players:GetPlayerFromCharacter(Part.Parent) then
			if not table.find(nearbyPlayers, Part.Parent.Name) then
				table.insert(nearbyPlayers, Part.Parent.Name)
			end
		end
	end
end)

Hitbox.TouchEnded:Connect(function(Part)
	if BValue.Value == true then
		if Part.Parent:FindFirstChild("Humanoid") and game.Players:GetPlayerFromCharacter(Part.Parent) then
			table.remove(nearbyPlayers, table.find(nearbyPlayers, Part.Parent.Name))
		end
	end
end)

while wait(2) do
	print(nearbyPlayers)
end

script is a server script inside the npc

image:


its printing an empty group even when theres a player touching it


after touching the part, only prints player1 instead of player 1 and 2


and when player 2 leaves and goes back, it only prints player 2

2 Likes

.Touched and .TouchEnded on its own are really bad for this purpose, as it’s not really accurate for knowing how many parts are within the bounds of a part.

(for example, if there is a part already touching, and the hitbox touches a new part, it will occasionally go on to fire both touchended and touched again for the previous part, which sucks!)

The solution is to pair up the touch and .Touched and .TouchEnded events with a workspace:GetPartsInPart(Hitbox),
and to only handle the inserting and removing of the table with the list of parts obtained from this function.

2 Likes

I tried it with .GetPartsInPart() but its not adding it to the table, also I dont really know how to use it since I just heard .GetPartsInPart() today, heres the script I made

local BValue = script.Parent:FindFirstChild("isAttacking")
local Hitbox = script.Parent:FindFirstChild("Hitbox")

local nearbyPlayers = {}

local touching = workspace:GetPartsInPart(Hitbox)

while wait() do
	print(nearbyPlayers)
	
	for i, part in pairs(touching) do
		if BValue.Value == true then
			if part.Parent:FindFirstChild("Humanoid") and game.Players:GetPlayerFromCharacter(part.Parent) then
				if not table.find(nearbyPlayers, part.Parent.Name) then
					table.insert(nearbyPlayers, part.Parent.Name)
				end
			end
		end
	end
end

also, when I start the game it detects the npc that owns the hitbox so when I made it only for a player, its not detecting the player when they touched the hitbox

1 Like

Put the GetPartsInPart code in the loop itself, you need to do it every time you want to check who’s touching, right now it’s only doing it once before the loop

3 Likes

oh thanks, I didnt know that I need to do that

1 Like

btw do y ou know how to make it detect if the touch have ended?? heres the script I have so far

local BValue = script.Parent:FindFirstChild("isAttacking")
local Hitbox = script.Parent:FindFirstChild("Hitbox")

local nearbyPlayers = {}


while wait() do
	local touching = workspace:GetPartsInPart(Hitbox) 
	
	print(nearbyPlayers)
	
	for i, part in pairs(touching) do
		if BValue.Value == true then
			if part.Parent:FindFirstChild("Humanoid") and game.Players:GetPlayerFromCharacter(part.Parent) then
				if not table.find(nearbyPlayers, part.Parent.Name) then
					table.insert(nearbyPlayers, part.Parent.Name)
				end
			end
		end
	end
end
1 Like

Hello! sorry i took a while, here’s what I meant for you to implement:

local BValue = script.Parent:FindFirstChild("isAttacking")
local Hitbox = script.Parent:FindFirstChild("Hitbox")

local nearbyPlayers = {}

--make a function to check the players within the hitbox
local function checkPlayersInZone()
    local listOfParts = workspace:GetPartsInPart(Hitbox)

    local newPlayerTable = {}

    for _,part in pairs(listOfParts) do

        if part.Name == "HumanoidRootPart" then
            local player = game.Players.GetPlayerFromCharacter(part.Parent)

            if player then
                --check if we haven't already added the player
                local alreadyHasPlayer = table.find(newPlayerTable, player)
                if not alreadyHasPlayer then
                    table.insert(newPlayerTable, player)
                end
            end
        end
        
    end

    --overwrite nearbyPlayers to the new table
    nearbyPlayers = newPlayerTable
end

--then just use the touched events to run the check
Hitbox.Touched:Connect(function(Part)
	if BValue.Value and game.Players:GetPlayerFromCharacter(Part.Parent) then
        checkPlayersInZone()
	end
end)

Hitbox.TouchEnded:Connect(function(Part)
	if BValue.Value and game.Players:GetPlayerFromCharacter(Part.Parent) then
        checkPlayersInZone()
	end
end)

while task.wait(2) do
	print(nearbyPlayers)
end
1 Like

if by that you mean to detect which players have left the zone, then you can just compare nearbyPlayers to the newPlayerTable (before overwriting) to see which players are no longer there

1 Like

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