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
.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.
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
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
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
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
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