Trouble making employee only doors

I am trying to make an employee only door for my restaurant. I did it once, and it worked. Here is the code:

local csEmployeeGate = script.Parent

local function blockCustomers(otherpart)
	local character = otherpart.Parent
	local humanoid = character:FindFirstChildWhichIsA("Humanoid")
	if humanoid then
		local rank = character.leaderstats:FindFirstChild("Rank")
		if rank == "Guest" or "Customer" or "Trainee" or "Junior Chef" or "Chef" or "Senior Chef" then
			csEmployeeGate.CanCollide = true
		else
			csEmployeeGate.CanCollide = false
		end
	end
end

csEmployeeGate.Touched:Connect(blockCustomers)

I’m trying to do it again, but the error shows up that leaderstats isn’t a valid member of the character (aka, the player trying to get through the door). Here is the code:

local rEmployeeGate = script.Parent

local function blockCustomers(otherpart)
	local character = otherpart.Parent
	local humanoid = character:FindFirstChildWhichIsA("Humanoid")
	if humanoid then
		local rank = character.leaderstats:FindFirstChild("Rank")
		if rank == "Guest" or "Customer" or "Trainee" then
			rEmployeeGate.CanCollide = true
		else
			rEmployeeGate.CanCollide = false
		end
	end
end

rEmployeeGate.Touched:Connect(blockCustomers)

How do I fix this?

I’m pretty sure leaderstats don’t need to be in the character.

The character is not the player itself. To get the player you use game.Players:GetPlayerFromCharacter(character)

As previously stated, use the Player rather than the Character. I just wanted to add looking at your script, have you tried using Player:GetRankInGroup? You can do something simple from this such as putting it in a LocalScript and doing the following:

if game.Players.LocalPlayer:GetRankInGroup(GroupID) >= GroupRoleRankToAccess then
	workspace.NameOfTheRankDoor.CanCollide = false 
end

Keep in mind to change GroupId, NameOfTheRankDoor and GroupRoleRankToAcess to the actual integer of the groupId, the refrence to the rank door in workspace and the rank you want to access.

Although the current script you have is fine adjusting it to the player rather than the character, down the road it might cause a few unexpected consequences doing it from the server, such as if two people try to enter at the same time who are different group ranks.

leaderstats should be in the Player, not the Character. Also your FindFirstChildWhichIsA(arg: string) is kinda useless, since there’s only ever one Humanoid object inside the character. So you can just do FindFirstChild("Humanoid") since the player character’s humanoid’s name should never be anything other than “Humanoid”.

Also you don’t want to make it can collide on when a customer walks into it, you want to make it can collide off when an employee walks into it. Take this psuedo code for example

-- Make sure door is CanCollide: true by default!
if employee_rank then
    door can_collide: false
    wait 0.05 seconds
    door can_collide: true
end

This way if a customer walks to the door they can’t get in at all. As the door is completely solid until an employee walks into it.

Also to make this more efficient, have a whitelist table in which you store all the strings that show which ranks can go in which doors.

See this psuedo code

white_list: table = {
    "Junior Chef",
    "Chef"
}

function: checkWhitelist(whitelist: table, rank: string)

    for key, value in pairs from white_list do
        if rank (equals) value then
            return true
        end
    end
    return false
end function

if checkWhitelist(white_list: table, "Chef: string) then -- returns true since it's in the table
  ---  allow through door code
end
1 Like

This line.
if rank == "Guest" or "Customer" or "Trainee" then
Needs to be the following.
if rank.Value == "Guest" or rank.Value == "Customer" or rank.Value == "Trainee" then

I’ll let someone else explain why.

As @Forummer said,

You’re comparing here 3 different ranks , noice :
You cant actually compare an instance to a string. You need the instance’s name [ in this case].

My note:
You could make a table for ranks, you then can loop through all of them, and see if the player’s rank is found there. And if it is, you could add special abilities to those ranks [ either inside the dictionary or outside, I’d probably give each rank its ‘packages/rewards’ inside that dictionary.].

Where would I put the local script?

Is the ‘rank’ object a ValueBase?

I don’t know what you mean, but it is a string value.

Should I put it in the door? I don’t really know where to put it.

Are you talking about the script I posted? If you want to go my route with this and make it 10x easier on yourself by using GetRankInGroup, you can put this in a LocalScript.

Because you need the door to be CanCollide true for some people, and CanColldie false for others, it’s better to adjust this locally.

This can probably be compacted to:

csEmployeeGate.CanCollide = table.find(allowedRanks, rank) ~= nil

–Edit:
I missed this reply when reading,

This is a better solution.
–Edit 2:
The above code can be “shortened” to

csEmployeeGate.CanCollide = game.Players.LocalPlayer:GetRankInGroup(GroupID) >= GroupRoleRankToAccess
1 Like

Yeah, but where do I put the local script? Do I just put it in server script service?

LocalScripts don’t belong in there and won’t have any effect if you put them in ServerScriptService. Try putting it in StarterPlayer instead, specifically StarterPlayerScripts would probably do the trick. Let me know if you get any errors associated with this.

1 Like

This worked very well, and I am very pleased with the results. You are a genius.

1 Like