Okay so, I was trying to create a Safe zone and It work at first code but it was firing remotes way too much since it works everytime a player’s part leaves or enters area And it will probably makes server too laggy so I Tried to use second code which takes just humanoid but it gave an
error 19: attempt to index nil with ‘Humanoid’
FirstCode
local SafeZone = script.Parent
local CframeOfBox = SafeZone.CFrame
local SizesOfBox = SafeZone.Size
local CollectionService = game:GetService("CollectionService")
local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local remotes = replicatedStorage:WaitForChild("Remotes")
local function Check(player)
local PlayerIsInTheZone = false
local InsideOfTheZoneParts = workspace:GetPartBoundsInBox(CframeOfBox,SizesOfBox,nil)
for _, i in pairs(InsideOfTheZoneParts) do
if i.Parent.Name == player.Name then
PlayerIsInTheZone = true
break
end
end
local Character = player.Character
if Character then
if PlayerIsInTheZone then
CollectionService:AddTag(Character, "SafeZone")
else
CollectionService:RemoveTag(Character,"SafeZone")
end
end
if CollectionService:HasTag(Character,"SafeZone") then
print("TestNumber2")
remotes.SafeZone:FireClient(player)
end
CollectionService:GetInstanceRemovedSignal("SafeZone"):Connect(function(Character)
print("TESTNUMVER1")
remotes.SafeZone:FireClient(player)
end)
end
while true do
wait(.2)
for i , v in pairs(players:GetChildren()) do
Check(v)
end
end
in SecondCode the only changes I did is trying to getting Humanoid and Changing “Character” variables to “Hum”
SecondCode=
local SafeZone = script.Parent
local CframeOfBox = SafeZone.CFrame
local SizesOfBox = SafeZone.Size
local CollectionService = game:GetService("CollectionService")
local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local remotes = replicatedStorage:WaitForChild("Remotes")
local function Check(player)
local PlayerIsInTheZone = false
local InsideOfTheZoneParts = workspace:GetPartBoundsInBox(CframeOfBox,SizesOfBox,nil)
for _, i in pairs(InsideOfTheZoneParts) do
if i.Parent.Name == player.Name then
PlayerIsInTheZone = true
break
end
end
local hum = player.Character.Humanoid -- Error points is here
if hum then
if PlayerIsInTheZone then
CollectionService:AddTag(hum, "SafeZone")
else
CollectionService:RemoveTag(hum,"SafeZone")
end
end
if CollectionService:HasTag(hum,"SafeZone") then
remotes.SafeZone:FireClient(player)
end
CollectionService:GetInstanceRemovedSignal("SafeZone"):Connect(function(hum)
print("TESTNUMVER1")
remotes.SafeZone:FireClient(player)
end)
end
while true do
wait(.2)
for i , v in pairs(players:GetChildren()) do -- and here
Check(v)
end
end
Connecting the same function many times during an event will cause to have multiple functions running, and multiple calls to the remote.
Follow this:
Theres 2 players in ther server
while true do
wait(.2)
for i , v in pairs(players:GetChildren()) do
Check(v)
Each 0.2 secs, you are calling Check() two times, cause theres 2 players
Each time Check() runs, its connecting/creating a new function which is firing the remote:
CollectionService:GetInstanceRemovedSignal("SafeZone"):Connect(function(Character)
print("TESTNUMVER1")
remotes.SafeZoneExit:FireClient(player) -- Here
second issue is how can I connect Check() 1 time for every player even there is a 2 player or more?
because even I remove that function
this remote event
end
end
if CollectionService:HasTag(Character,"SafeZone") then
remotes.SafeZone:FireClient(player)
print("PlayerIsInSafeZone")
end
end
will still fire 10 times if there are 2 player in the safe zone and it is bad, should I remove that part from the Check() function too and use CollectionService:GetInstanceAddedSignal ?
That’s because the only time you define player is as a parameter of the check function.
Changing in itself this won’t do anything. That isn’t a player object, that’s a humanoid, from what I can see in your script. You can however, get the player from that, using game.Players:GetPlayerFromCharacter(hum.Parent)
well I can’t use hum.parent because this time it will probably say unknown global “hum” since hum is only defined as a parameter in the check function I can’t test because I am not in home or close to pc. but it won’t probably
btw I am currently using 1st script With “Character” not “hum” since peashie said problem is not with number of player parts well won’t make any chance probably just want to say to avoid confusion
It’s not.
Just change the parameter from player in the GetInstanceRemovedSignal to hum or humanoid for less confusion. Judging by your script, the only thing that parameter will ever be is a humanoid.
Okay rightnow I am really feeling deeply embrassed and stupid to still not able to fix it and asking for it but this is the whole code
local SafeZone = script.Parent
local CframeOfBox = SafeZone.CFrame
local SizesOfBox = SafeZone.Size
local CollectionService = game:GetService("CollectionService")
local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local remotes = replicatedStorage:WaitForChild("Remotes")
local function Check(player)
local PlayerIsInTheZone = false
local InsideOfTheZoneParts = workspace:GetPartBoundsInBox(CframeOfBox,SizesOfBox,nil)
for _, i in pairs(InsideOfTheZoneParts) do
if i.Parent.Name == player.Name then
PlayerIsInTheZone = true
break
end
end
local Hum = player.Character.Humanoid
if Hum then
if PlayerIsInTheZone then
CollectionService:AddTag(Hum, "SafeZone")
else
CollectionService:RemoveTag(Hum,"SafeZone")
end
end
end
local player =game.Players:GetPlayerFromCharacter(Hum.Parent) -- Unknown Global hum error here
CollectionService:GetInstanceAddedSignal("SafeZone"):Connect(function(Hum)
print("TestNumber1")
remotes.SafeZone:FireClient(Hum)
end)
CollectionService:GetInstanceRemovedSignal("SafeZone"):Connect(function(Hum)
print("TESTNUMVER1")
remotes.SafeZoneExit:FireClient(Hum)
end)
while true do
wait(.2)
for i , v in pairs(players:GetChildren()) do
Check(v)
end
end
and if I place this part of code to inside of check() function
local player =game.Players:GetPlayerFromCharacter(Hum.Parent)
then
it gives error here
local Hum = player.Character.Humanoid -- index nil with "Humanoid"
Another alternative is to use ZonePlus .It’s useful module to detect if a player entered a part or left a part.
Have a look:
After grabbing the module put it in ReplicatedStorage and name it “Zone” and drop this code into your script.
local Zone = require(game:GetService("ReplicatedStorage").Zone)
local SafeZone = -- PATH TO YOUR SAFEZONE PART
local zone = Zone.new(container)
zone.playerEntered:Connect(function(player)
-- Let the player be safe, he entered the safe zone.
end)
zone.playerExited:Connect(function(player)
-- Let the Player not be safe anymore, he left the safe zone.
end)
Yeah I have seen ZonePLus before but Idk why I am not using it maybe because of that ForceField pop up or I hate the idea of using someone else is code or maybe A part of myself wants to learn how to do it with mistakes
I really don’t know the reason well since many people are using it, it is probably safe but still I don’t want to use it but thanks for advice
I bet since this is always running, it runs before the character is loaded, and thus Humanoid doesn’t exist, which is supported by the error.
Try changing Line 19 to
local Hum
if player.Character then
Hum = player.Character:WaitForChild("Humanoid")
else
return
end
Awesome!
Also, I’m just realizing now that in your script you have an if statement to check for Hum, so you can either get rid of that or get rid of the “else return” when you set Hum, and it should still work.