I took the help of a tutorial for the door and I would like to learn how to add a text when a player already has something, this could be used to make,
for example:
a text that appears when a player touches a part (joins the group) and when he joins the group, and he touches the part, the text does not appear
currently I made a door with a pass card, I displayed a text when the player touches the hitbox but the problem is that, I would like to display the text only when the player does not have a card, and check if the player has the card then don’t show the text, how to do it please?
local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true
touchpart.Touched:Connect(function(hit)
if canhit == true then
local name = hit.Parent.Name
if hit and hit.Parent:FindFirstChild("Humanoid") then
text.Visible = true
for i,p in pairs(game.Players:GetChildren()) do
if p.Name == name then
canhit = false
text.Visible = true
wait(3)
text.Visible = false
canhit = true
break
elseif p.Name ~= name then
text.Visible = false
end
end
end
local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
if Tool then
text.Visible = false
end
end
end)
Make a script inside ServerScriptStorage, and write these code in it:
local groupID = 0 -- Your Group Id here
game:GetService("Players").PlayerAdded:Connect(function(plr)
if plr:IsInGroup(groupID) then
plr.PlayerScripts:WaitForChild("IsInGroup").Value = true -- Change "IsInGroup" with your variable's name
end
end)
Add these codes to your door’s script:
local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true
local isInGroup = player.PlayerScripts:WaitForChild("IsInGroup") -- Change "IsInGroup" with your variable's name
touchpart.Touched:Connect(function(hit)
if canhit == true then
local name = hit.Parent.Name
if hit and hit.Parent:FindFirstChild("Humanoid") then
text.Visible = true
for i,p in pairs(game.Players:GetChildren()) do
if p.Name == name and isInGroup == true then
canhit = false
text.Visible = true
wait(3)
text.Visible = false
canhit = true
break
elseif p.Name == name and isInGroup == false then
text.Visible = true
elseif p.Name ~= name then
text.Visible = false
end
end
end
local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
if Tool then
text.Visible = false
end
end
end)
You may want to make sure the text disappears when he’s not touching the door anymore (If they don’t join the group)
You can read this article instead, may it helps you either.
It was stated that
The IsInGroup Player function sends a request to the Roblox website asking whether a player is a member of a group, given the ID of that group.
Using this in a Script, as opposed to a LocalScript, will not get you the most up-to-date information. If a player leaves a group while they are in the game, IsInGroup will still think they’re in that group until they leave. However, this does not happen when used with a LocalScript.
This is because the method caches results, so multiple calls of IsInGroup on the same player with the same group ID will yield the same result as when the method was first called with the given group ID. The caching behavior is on a per-peer basis: a server does not share the same cache as a client.
i will help you for the “Tool” Check script soon.
local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true
touchpart.Touched:Connect(function(hit)
if canhit == true then
local name = hit.Parent.Name
if hit and hit.Parent:FindFirstChild("Humanoid") then
local hasKeyCard = false
-- Check if the player has the key card
local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
if Tool then
hasKeyCard = true
end
if not hasKeyCard then
text.Visible = true
wait(3)
text.Visible = false
end
end
end
end)
local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true
touchpart.Touched:Connect(function(hit)
if canhit == true then
local name = hit.Parent.Name
if hit and hit.Parent:FindFirstChild("Humanoid") then
local hasKeyCard = false
-- Check if the player has the key card
local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD")
if Tool then
hasKeyCard = true
end
if not hasKeyCard then
text.Visible = true
wait(3)
text.Visible = false
end
end
end
end)
Take note that you don’t necessarily need to use for i,v in pairs
Yes please I am not planning to add the isInGroup function at the moment, I prefer do 1 task per 1 task,
and I tried to modify your script to remove the isInGroup function but I think I broke everything I don’t have the skills yet to be able to modify such a thing.
Are you trying to make the door passable when the Tool named “KEYCARD” is available in the player’s backpack ?
Well, this is what i expect it gonna be
local touchpart = game.Workspace:WaitForChild("Game"):WaitForChild("System"):WaitForChild("KeycardDoor"):WaitForChild("hitbox")
local player = game.Players.LocalPlayer
local text = player.PlayerGui.Notif.Text
local canhit = true
touchpart.Touched:Connect(function(hit)
local Tool = player.Backpack:FindFirstChild("KEYCARD") or player.Character:FindFirstChild("KEYCARD") -- If none found = nil
if canhit == true then
local name = hit.Parent.Name
if hit and hit.Parent:FindFirstChild("Humanoid") then
text.Visible = true
for i,p in pairs(game.Players:GetChildren()) do
if p.Name == name then
if Tool then -- If the thing that touches the door is player and they was found to have the KEYCARD then proceed
canhit = false
text.Visible = true
wait(3)
text.Visible = false
canhit = true
else -- If they are player who touches the door but was found have no tool named "KEYCARD" in their backpack nor character
text.Visible = true
end
break
elseif p.Name ~= name then -- if its not a player's character
text.Visible = false
end
end
end
end
end)
touchpart.TouchEnded:Connect(function(hit) -- making sure the text go unvisible when the player stop touching it (whose who dont have the keycard)
text.Visible = false
end)
That local canhit = true is optional variable to write, developers wrote it so they can disable some statements incase there are any bugs in future development
the if not hasKeyCard then > text.Visible = false will’nt make the Door to tell the player that they need the Keycard to pass
But, if your question is why don’t we just write if not hasKeyCard then > text.Visible = true, the last code is making sure that the text won’t gone visible forever when the player leave the door untouched.
I have one last question and then I can finish my first task ^^
I used a tutorial to do the door, the problem is that the person does it in a script and I would like to put it in a local script so that it is on the client and not on the server, I didn’t find an explanation about this,
do I have to change the script or smth, because when I try to copy and paste that into the localscript and I check if everything is good, nothing works,
I’m sure I’m missing something to know to understand why a script and a local script do not work the same way
here is the code :
local door = script.Parent:WaitForChild("Door")
if not door.PrimaryPart then
door.PrimaryPart = door:WaitForChild("HINGE")
end
--CONFIGURATION--
local keycardName = "KEYCARD"
local timeOpen = 8
local goalRot = 105
local openLength = 2
local closeLength = 1.2
-----------------
local pos = door:GetPivot().Position
local initialRot = door.PrimaryPart.Orientation.Y
local opened = false
local animationHappening = false
local prompt = Instance.new("ProximityPrompt")
prompt.ObjectText = "Keycard Door"
prompt.ActionText = "Open door"
prompt.KeyboardKeyCode = Enum.KeyCode.E
prompt.HoldDuration = 0
prompt.RequiresLineOfSight = false
prompt.MaxActivationDistance = 8
prompt.Parent = door
local cfv = Instance.new("CFrameValue")
cfv.Value = door:GetPivot()
cfv.Parent = door
cfv:GetPropertyChangedSignal("Value"):Connect(function()
door:PivotTo(cfv.Value)
end)
function ease(x)
local n1 = 7.5625
local d1 = 2.75
if (x < 1 / d1) then
return n1 * x * x
elseif (x < 2 / d1) then
x -= 1.5/d1
return n1 * (x) * x + 0.75
elseif (x < 2.5 / d1) then
x -= 2.25/d1
return n1 * (x) * x + 0.9375
else
x -= 2.625/d1
return n1 * (x) * x + 0.984375
end
end
function closeDoor()
if opened and not animationHappening then
opened = false
animationHappening = true
local currentRot = door.PrimaryPart.Orientation.Y
local closeStarted = tick()
while true do
local x = (tick() - closeStarted) / closeLength
local rotOffset = ease(x) * -goalRot
cfv.Value = CFrame.new(pos) * CFrame.Angles(0, math.rad((initialRot + goalRot) + rotOffset), 0)
if x >= 1 then
break
end
game:GetService("RunService").Heartbeat:Wait()
end
animationHappening = false
prompt.Enabled = true
end
end
function openDoor()
if not opened and not animationHappening then
opened = true
animationHappening = true
prompt.Enabled = false
local openStarted = tick()
while true do
local x = (tick() - openStarted) / openLength
local rotOffset = ease(x) * goalRot
cfv.Value = CFrame.new(pos) * CFrame.Angles(0, math.rad(initialRot + rotOffset), 0)
if x >= 1 then
break
end
game:GetService("RunService").Heartbeat:Wait()
end
animationHappening = false
end
end
prompt.Triggered:Connect(function(plr)
local char = plr.Character
if char and char:FindFirstChild("Humanoid") and char.Humanoid.Health > 0 then
if char:FindFirstChild(keycardName) and char[keycardName]:IsA("Tool") then
task.spawn(openDoor)
task.wait(timeOpen)
task.spawn(closeDoor)
end
end
end)
When moving code from a regular Script to a LocalScript, it’s important to understand the differences between the two:
Scope: A Script runs on the server and has access to all game data and services, while a LocalScript runs on the client and only has access to client-side objects and services.
Replication: LocalScripts run on each player’s device independently, so they can’t access information about other players directly or perform actions that affect the game state for everyone. They can only manipulate objects and data that are specific to the player running the LocalScript.
Performance: LocalScripts should primarily handle UI, input, and client-side effects. Heavy computation or server-related tasks should still be done on the server.
However, you’re checking for the existence of a tool in the player’s inventory (char:FindFirstChild(keycardName)), which involves checking the player’s data, and then triggering actions based on that. This requires server-side checks.
You can seperate the script to client-server communicating script if you need it to be put on client side.
That’s actually an awesome way to learn about how roblox is managing your data in the game.
If you need to finish it instead of learning, you can follow the whole tutorial without changing anything important unless you know what you’re doing.
From what i research from the script, you only need to put the “Checking the tool” statements to server-side. And create new statements to make the communicate and check if the player really have it.
If they have it you can start the animation of the door