Do you know tycoon doors that only a specific player can pass through it? This is the idea: make a specific player pass through the part.
You can make designs for it if you want. Everything you have to do is put the script inside the part that will be opened.
- This isn't a tycoon door;
- Other players can pass through it if opened;
- If it isn't working, check if you wrote correctly the player's Name/ID
- You can also check for the debugging tutorial in Lua Learning if it still doesn't work
So first, you need to get or create your part that will be the door. You can name it whatever you want (the name wont be used in the script). Once done, you add a script inside it. Now you might ask: "How am I making the door open?". It's pretty simple: you just need to create an event to detect when player's character touches it.
local door = script.Parent
door.Touched:Connect(function(hit)
end)
Perfect. Now it is checking if another part has touched the door part. If you run, nothing happens. How do we check if the player whose touched is the one that I want?
For this, we are using an if
statement.
local door = script.Parent
door.Touched:Connect(function(hit)
if hit:FindFirstAncestorWhichIsA("Model").Name == "" then --Put the player's name between the double quotes
end
end)
Now it is checking if the player's name is the one that you've chosen. If you run, nothing happens again. "But we have detected if the player touched the part!"; Yes, we do, but we didn't tell it what should happen now. For this case, we need to make some customizations on our door. You can choose some of them for whatever you want, but not all of them. I'll write what you can change:
local door = script.Parent
door.Touched:Connect(function(hit)
if hit:FindFirstAncestorWhichIsA("Model").Name == "" then
door.CanCollide = false --Don't change.
door.Transparency = 0.7 --You can change.
wait(1.4) --You can change.
door.CanCollide = true --Don't change
door.Transparency = 0 --You can change.
end
end)
So, what is happening here? When we used CanCollide
for the first time, we changed the Door property so it can't be collided (Parts can pass through it), then when we used the second time, we chaned it to can be collided (Parts can't pass through it). When we used Transparency
, we are doing what the names supposes: changing the transparency of the Door. If we set it to 1 the Door will be invisible, and the lower it is, more visible it becomes. (Remember that 0 is the lowest and 1 the highest)
Done! Now you have a door that will open when this player touches it. Again, other players can pass it if it's opened, and that's why I put 1.4 seconds to it close again.
Ok, to make this we start the same way: create a Part/Model that will be your door ==> Insert a Script inside the Part that will be opened. Now that you have the Part/Model created, we will start as the same way: creating the Touched event connected to a function.
local door = script.Parent
door.Touched:Connect(function(hit)
end)
"Oh, ok. But if I remember correctly, you said it will do nothing, right?"; Yes, buddy. If you skipped the begin of the tutorial, I'll explain. Else, you can go to the next paragraph if you want to. Here's the explanation: You created the Touchedevent, but didn't tell the script what to do next. Inside it to test, add print("Touched")
, and touch the part. If everything was made correctly, you saw Touched in the output. Else, check again if what you wrote is correct. You can remove it if worked, but you can leave it there if wanted.
"Sintz, what do we do to check if the player that triggered the event has the ID I want?"; There is a function called GetPlayerFromCharacter()
. We're going to use it to get the Player. "I saw that if we write 'game.Players.LocalPlayer' you can get it! Why don't we use it? It's sooo simpler."; We can't use it. You can't get the LocalPlayer from a Script, only LocalScript. Let's do the other piece of code:
local door = script.Parent
door.Touched:Connect(function(hit)
local LocalPlayer = game.Players:GetPlayerFromCharacter(hit:FindFirstAncestorWhichIsA("Model")) --Assign it to a variable, so it's easier
end)
Remember: the variable name can be any, it won't change anything, but make it a clear and easy to read name, so you remember what it does
So here, we assigned the player to hit:FindFirstAncestorWhichIsA("Model")
. Remember that hit is what touched and its first ancestor which is a model is, well, the "dad" of the Instance that is a model. It's a little bit hard to explain, but you probably got the idea. "Great, now I just copy the rest and done! Thanks, Sintz!"; Not quite. We'll fix something that will most likely break everything if you just copy and paste the rest. The issue is that GetPlayerFromCharacter()
requires the character as an argument (check functions if you don't know what this means), and it is not certain that it will always return the character. We need to make sure that if it doesn't get the right argument our code doesn't throw an error.
local door = script.Parent
door.Touched:Connect(function(hit)
local LocalPlayer = game.Players:GetPlayerFromCharacter(hit:FindFirstAncestorWhichIsA("Model"))
if LocalPlayer then
end
end)
With this if statement, we check if the LocalPlayer variable exists (is not nil). We now need to check if the player's ID is the one you chose. Note that this function returns the LocalPlayer (game:GetService("Players").LocalPlayer
) or nil if not found. We use this instead of the method between the parenthesis because we can't directly get the LocalPlayer from a Script.
local door = script.Parent
door.Touched:Connect(function(hit)
local LocalPlayer = game.Players:GetPlayerFromCharacter(hit:FindFirstAncestorWhichIsA("Model"))
if LocalPlayer and LocalPlayer.UserId == 123456 then --Change 123456 to the ID you want
end
end)
Great, the script is now checking if the given ID is from the player that touched the Part. If it is, then something will happen, if it isn't it won't happen. It also checks if LocalPlayer exists, so it won't error when using UserId. Now let's tell the code what to do if the ID is right. In our case, we want it to open our Door, so we are using the CanCollide property (mainly), and to have visual assistance, the Transparency property. CanCollide will make the Part be collidable or not. Transparency is the much we can see through the Part. The transparency property can be changed, but not the CanCollide. I'll write better in the sample:
local door = script.Parent
door.Touched:Connect(function(hit)
local LocalPlayer = game.Players:GetPlayerFromCharacter(hit:FindFirstAncestorWhichIsA("Model"))
if LocalPlayer and LocalPlayer.UserId == 123456 then --Change 123456 for the ID you want
door.CanCollide = false --Don't change it. If you do so it'll not work
door.Transparency = 0.6 --You can change it
wait(1.4) --You can change it. It'll define the ammount of time before the door closes
door.CanCollide = true --Don't change it
door.Transparency = 0 --It's ok change it
end
end)
Wow! We did it! We finally made this door work! Now if everything was made correctly, the door will open if the ID is the same as the given one.
Remember: if you write the ID incorrectly the door will not open!
"Can I have many names inside the double quotes?"; Not inside the same, but if you write the name, put or and another name. Example:
--The begin of the code
if hit.Parent.Name == "Name1" or hit.Parent.Name == "Name2" then --Yes, you need to write "hit.Parent.Name" again.
--Code continues
You can also scroll down to see another way to do it.
"My code doesn't work, and I wrote my name correctly!"; Be sure of: the script is inside the part that will open, not the model or another part or ServerScriptService; you wrote the code correctly; you didn't mess up while writing the parameter and using it (changing a letter or something like that).
"I saw the example of 2 names, but can I type more?" Yes, but you'll need to copy and paste the line of the code again. Example:
if hit.Parent.Name == "Name1" or hit.Parent.Name == "Name2" or hit.Parent.Name == "Name3" or hit.Parent.Name == "Name4" then -- You can type how many names you wanna if you do it like this
Or you can do it in a simpler way. You'll use tables
--The script needs to be inside the part that will open
local Names = {"Name1","Name2"} --Put how many names you wanna, but keep in mind that you'll still use the double quotes
script.Parent.Touched:Connect(function(hit)
for _,name in pairs(Names) do --This will iterate through all the names you've put inside the table.
if hit.Parent.Name == name then
script.Parent.CanCollide = false
script.Parent.Transparency = 0.7
wait(1.4) --You can change.
script.Parent.CanCollide = true
script.Parent.Transparency = 0
end
end
end)
--This also works for the IDs
--The only difference is the *for* loop
I'm not going in a deep explanation about for loops, but _,names is like doing _,v. I used underscore instead of i because I do not need the index. For any further help about for loops, check out about loops (I think there is a tutorial here about it)
"Everything else worked, it just won't become solid again"; Ok, if it isn't becoming solid, then check if you wrote everything after the wait(1.4) correctly. This will fix it.
"I followed everything correctly but it doesn't work"; If you are 100% sure it is not working even if the code is identical, check the following: 1. The script is inside of the part that you're going to 'open'; 2. It is a Script and not a LocalScript; 3. If you're not using script.Parent to get the part, be sure you wrote the right path (e.g. game:GetService("Workspace").MyCoolPart). If it doesn't fix then check NotPorgu's debugging tutorial and check what is going on. I hope that helps you.
Thank you for reading this. Hope you learnt how to make it :)