Helo Everyone.
Right now i am coding on a Simulator Door system to unlock Doors but with a Path system so you cannot unlock a Door from another Path when you haven’t unlocked all the doors of your current Path, for example:
I open a Door from the Path “Nature” and there are currently 3 doors with the Path-attribute “Nature” but i can still open a door from the Path “Ice” even tho i havent opend every door from nature. I already asked Ai but it was not helpful. Can someone Help me with this Problem, down below is the LocalScript is use.
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local player = Players.LocalPlayer
if not player then
return
end
local doorsFolder = Workspace:WaitForChild("Doors")
local doorEvents = ReplicatedStorage:WaitForChild("DoorEvents")
-- Store which paths the player has unlocked
local unlockedPaths = {}
-- Format large numbers
local function formatNumber(n)
local suffixes = { "", "K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc", "No" }
local i = 1
while n >= 1000 and i < #suffixes do
n = n / 1000
i += 1
end
local formatted = string.format("%.2f", n)
formatted = formatted:gsub("%.0+$", ""):gsub("(%.%d-)0+$", "%1")
return formatted .. suffixes[i]
end
-- Smoothly hide a door with animation
local TweenService = game:GetService("TweenService")
-- Fade out part to simulate fog and play sound for the player
local function fadePartToFog(part, player)
if part:IsA("BasePart") then
-- Tween to make it fade like fog (increasing transparency)
local tweenInfo = TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local goal = { Transparency = 1 }
local tween = TweenService:Create(part, tweenInfo, goal)
tween:Play()
-- Find the UnlockSound part and play the sound for the player
local soundPart = part:FindFirstChild("UnlockSound")
if soundPart and soundPart:IsA("Sound") then
-- Clone the sound to avoid multiple players hearing it at once
local soundClone = soundPart:Clone()
soundClone.Parent = part
soundClone:Play()
-- Optionally clean up the sound after it finishes playing
game:GetService("Debris"):AddItem(soundClone, soundClone.TimeLength)
end
-- Optional: Add fog-like particle effect
local particle = Instance.new("ParticleEmitter")
particle.Texture = "rbxassetid://243098098" -- Example fog texture
particle.Rate = 50
particle.Lifetime = NumberRange.new(2)
particle.Size = NumberSequence.new(0.5, 1)
particle.Parent = part
-- Clean up the particle effect after it fades
game:GetService("Debris"):AddItem(particle, 2)
end
end
-- Fade out the door and parts in the Fog Folder, and play sound for the unlocking player
local function fadeOutDoor(door, player)
if not door or not door:IsDescendantOf(game) then return end
-- Safely remove children
local infoUI = door:FindFirstChild("DoorInfomations")
if infoUI then infoUI:Destroy() end
local attachment = door:FindFirstChild("Attachment")
if attachment then attachment:Destroy() end
local fogFolder = door:FindFirstChild("Fog Folder")
-- Fade the door itself
fadePartToFog(door, player)
-- Fade all parts inside the Fog Folder
if fogFolder then
for _, part in ipairs(fogFolder:GetChildren()) do
fadePartToFog(part, player)
end
end
-- Schedule cleanup AFTER fade is done (3 seconds)
delay(3, function()
if door and door:IsDescendantOf(game) then
door:Destroy()
end
end)
end
local function destroyDoor(door)
door:Destroy()
end
-- Track which paths the player has unlocked
local unlockedPaths = {}
-- Check if the player can unlock a door from a given path
local function canUnlockPath(path)
-- If the path has no doors, allow unlocking it
if not path then
return true
end
-- If the player hasn't unlocked any paths, they can choose any path
if #unlockedPaths == 0 then
return true
end
-- Check if all doors in the current path have been unlocked
if unlockedPaths[path] == nil then
-- Check if all doors in the current path are unlocked
for _, door in pairs(doorsFolder:GetChildren()) do
if door:GetAttribute("Path") == path then
local ownedVal = player:FindFirstChild("Doors"):FindFirstChild(door.Name)
if ownedVal and not ownedVal.Value then
return false
end
end
end
-- If all doors in the path are unlocked, mark the path as unlocked
unlockedPaths[path] = true
return true
end
-- Return whether the path is unlocked
return unlockedPaths[path] == true
end
-- Function to handle unlocking a door
local function unlockDoor(door)
local path = door:GetAttribute("Path")
if path and not canUnlockPath(path) then
-- Show message or handle logic for not being able to unlock this path
return
end
-- Handle unlocking the door as normal
doorEvents:WaitForChild("Buy"):FireServer(door.Name)
end
-- Update the UI for doors with path information
local function updateDoorUI(door)
if not door or not door:IsDescendantOf(game) then return end
local cost = door:GetAttribute("Cost")
local currencyName = door:GetAttribute("Currency")
local ownedVal = player:FindFirstChild("Doors"):FindFirstChild(door.Name)
if not ownedVal then return end
local owned = ownedVal.Value
local currencyStat = player:FindFirstChild("leaderstats"):FindFirstChild(currencyName)
if not currencyStat then return end
local currencyVal = currencyStat.Value
local gui = door:FindFirstChild("DoorInformations")
if not gui then return end
gui:FindFirstChild("Doorname").Text = door.Name
if cost > 100000 then
gui.Cost.Text = formatNumber(cost)
else
gui.Cost.Text = tostring(cost):reverse():gsub("(%d%d%d)", "%1."):reverse():gsub("^%.", "")
end
gui:FindFirstChild("ImageBackground").Visible = (currencyName == "Coins")
gui.Cost.Visible = not owned
gui.Close.Visible = not owned
gui.Doorname.Visible = not owned
if owned then
fadeOutDoor(door)
else
local textColor = currencyVal >= cost and Color3.fromRGB(0, 255, 0) or Color3.fromRGB(255, 0, 0)
gui.Cost.TextColor3 = textColor
gui.Close.TextColor3 = textColor
end
end
-- Initial door setup
for _, door in pairs(doorsFolder:GetChildren()) do
local ownedVal = player:WaitForChild("Doors"):WaitForChild(door.Name)
if ownedVal.Value == true then
fadeOutDoor(door)
else
updateDoorUI(door)
end
end
-- Update UI when currency changes
local trackedCurrencies = {}
for _, door in pairs(doorsFolder:GetChildren()) do
local currencyName = door:GetAttribute("Currency")
if not trackedCurrencies[currencyName] then
trackedCurrencies[currencyName] = true
local currencyStat = player.leaderstats:FindFirstChild(currencyName)
if currencyStat then
currencyStat.Changed:Connect(function()
for _, d in pairs(doorsFolder:GetChildren()) do
if d:GetAttribute("Currency") == currencyName then
updateDoorUI(d)
end
end
end)
end
end
end
-- Handle buying a door from prompt
doorEvents:WaitForChild("Door").OnClientEvent:Connect(function(doorName)
local door = doorsFolder:FindFirstChild(doorName)
if not door then return end
local cost = door:GetAttribute("Cost")
local currency = door:GetAttribute("Currency")
local currencyVal = player.leaderstats:FindFirstChild(currency).Value
local owned = player:WaitForChild("Doors"):WaitForChild(doorName).Value
-- Check if the player can unlock the door based on the path
local path = door:GetAttribute("Path")
if path and not canUnlockPath(path) then
-- Optionally show a message about the path not being unlocked
return
end
if not owned and currencyVal >= cost then
doorEvents:WaitForChild("Buy"):FireServer(doorName)
end
end)
-- Smoothly fade out a door when bought
-- Handle the door fade and removal when the ChangeDoor event is triggered
doorEvents:WaitForChild("ChangeDoor").OnClientEvent:Connect(function(doorName)
local door = doorsFolder:FindFirstChild(doorName)
if door then
-- Add path to unlockedPaths if it's the first door unlocked in a path
local path = door:GetAttribute("Path")
if path and not unlockedPaths[path] then
unlockedPaths[path] = true
end
-- Hide GUI elements associated with the door
local gui = door:FindFirstChild("DoorInformations")
if gui then
gui.Cost.Visible = false
gui.Close.Visible = false
gui.Doorname.Visible = false
end
-- Call the fade-out and destroy function to visually remove the door
fadeOutDoor(door)
end
end)
-- Update UI for doors when currencies change
for _, door in pairs(doorsFolder:GetChildren()) do
updateDoorUI(door)
end
doorsFolder.ChildAdded:Connect(function(newDoor)
print("🆕 New door added:", newDoor.Name)
task.wait(0.5)
updateDoorUI(newDoor)
end)
for _, door in pairs(doorsFolder:GetChildren()) do
print("🔍 Found door:", door.Name)
updateDoorUI(door)
end
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.