Hi! I’ve been working on a VC hangout game similar to ‘the interview’ where you can claim rooms and other stuff. To do this I need to track who enters and leaves each room. I did this by inserting an empty value with it’s name as the player’s user id into a folder inside the room model. While I was looking for bugs I noticed that if you leave or enter the room while you’re dead (as in if your body parts touch or stop touching the part while dead or if you die in the room and respawn outside). This is the error I get:
I can only assume this is because the character doesn’t exist while it’s dead, but I really don’t know what the problem is.
Specifically, the problem is this line of code, which is checking if there is something inside of the folder with it’s name set to the player’s user id (checking if the player is already in the room or not):
if playersInRoom:FindFirstChild(players:GetPlayerFromCharacter(char).UserId) then
Here are the full two functions if required:
Code
touchPart.Touched:Connect(function(hit)
local char = hit.Parent
if char:FindFirstChild("Humanoid") then
if not playersInRoom:FindFirstChild(players:GetPlayerFromCharacter(char).UserId) then
local playerVal = Instance.new("ObjectValue")
playerVal.Parent = playersInRoom
playerVal.Value = players:GetPlayerFromCharacter(char)
playerVal.Name = players:GetPlayerFromCharacter(char).UserId
end
end
end)
touchPart.TouchEnded:Connect(function(hit)
local char = hit.Parent
if char:FindFirstChild("Humanoid") then
if playersInRoom:FindFirstChild(players:GetPlayerFromCharacter(char).UserId) then
playersInRoom[players:GetPlayerFromCharacter(char).UserId]:Destroy()
end
end
if #playersInRoom:GetChildren() == 0 then
unlock()
end
end)
Thank you in advance to anyone taking the time to respond!
PlayersInRoom is a folder storing values with names of the players in the room’s user ids. If i do this then it will say the player is still in the room even if that is not the case.
local player = Players:GetPlayerFromCharacter(char)
if not player then
-- handle nil
end
if playersInRoom:FindFirstChild(player.UserId) then
-- ...
end
touchPart.TouchEnded:Connect(function(hit)
local char = hit.Parent
if char:FindFirstChild("Humanoid") then
local player = players:GetPlayerFromCharacter(char)
if player then
if playersInRoom:FindFirstChild(players:GetPlayerFromCharacter(char).UserId) then
playersInRoom[players:GetPlayerFromCharacter(char).UserId]:Destroy()
end
end
end
if #playersInRoom:GetChildren() == 0 then
unlock()
end
end)
The thing is, if the player doesn’t exist, the value representing the player won’t get removed, which is exactly my problem and why I didn’t do this to begin with.
i got a simmilar error in my old obby game
what i did was tracking if the player is alive in a variable and i checked if the player is alive in if statments before doing my logic
local Uis = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local dir = nil
local Humanoid :Humanoid = Character.Humanoid
local HumIsAlive = true
Humanoid.StateChanged:Connect(function(old, new)
if new.Name == "Dead" then
HumIsAlive = false
else
HumIsAlive = true
end
end)
if HumIsAlive and [ur other logic here] then
end
amnot sure if this is a perfect way of doing it tho
The problem, is that when you are doing playersInRoom:FindFirstChild(players:GetPlayerFromCharacter(char).UserId), the :GetPlayersFromCharacter(char) function might return nil. I modified your original code to fix this problem.
touchPart.Touched:Connect(function(hit)
local char = hit.Parent
if char:FindFirstChild("Humanoid") then
local player = players:GetPlayerFromCharacter(char)
if not player then return end
if not playersInRoom:FindFirstChild(player.UserId) then
local playerVal = Instance.new("ObjectValue")
playerVal.Parent = playersInRoom
playerVal.Value = player
playerVal.Name = player.UserId
end
end
end)
touchPart.TouchEnded:Connect(function(hit)
local char = hit.Parent
if char:FindFirstChild("Humanoid") then
local player = players:GetPlayerFromCharacter(char)
if not player then return end
if playersInRoom:FindFirstChild(player.UserId) then
playersInRoom[player.UserId]:Destroy()
end
end
if #playersInRoom:GetChildren() == 0 then
unlock()
end
end)
If the :GetPlayersFromCharacter(char) function returns nil and the code continues to run, you will eventually attempt to read the UserId property of the player instance that this function is supposed to return, but since it returned nil, then what will happen is it will error, because at this point the script is attempting to read the UserId property of… well… nothing…
Edit: I also added a little optimization because you were calling the :GetPlayersFromCharacter(char) function multiple times, instead of calling it once, and storing it’s value in a variable, and then just using the value stored inside of the variable, instead of needlessly calling that function over, and over again.
Thanks for your reply. Unfortunately, my original problem was that if the function returns nothing (when the player dies), the player is still in the room folder, even if the player has respawned outside of the room or body parts leave the room while dead. I managed to fix my problem by adding this:
players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
char:WaitForChild("Humanoid").Died:Connect(function()
for i, v in pairs(playersInRoom:GetChildren()) do
if v:IsA("ObjectValue") then
if v.Value == plr then
task.wait(4)
v:Destroy()
end
end
end
end)
end)
end)