What do you want to achieve? Keep it simple and clear!
I want to make a window system similar to a fnaf closet system like this
kind of like this but you can exit it and walk around the rest of the house
What is the issue? Include screenshots / videos if possible!
i have no idea to go about doing this since i need to do this for several windows and the issue is knowing which window to close and the game is multiplayer so i need to add a check for their to only be one person on a window at a time
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
ive written some code to go about doing this but the problem im encountering is theoretically i could do this but im gonna have to have like 30 functions for each window and and still a lot of problems
im not really looking for code but this is what i have so far im more looking for a way to do this efficiently or just a way to do this
local Player = game.Players.LocalPlayer
-- Window variables
local WindowFolder = game.Workspace.Windows
local Window1 = WindowFolder.Window1
local Window2 = WindowFolder.Window2
local TouchWindow1 = Window1.TouchWindowPart1
local TouchWindow2 = Window2.TouchWindowPart2
-- windowCamPart
local WindowCam = game.ReplicatedStorage.WindowCamera:Clone()
-- config
local WindowConfig = game.ReplicatedStorage.WindowSystem
-- boolvalues
local CurtainsClosed1 = WindowConfig.CurtainsClosed1
local CurtainsClosed2 = WindowConfig.CurtainsClosed2
local UIS = game:GetService("UserInputService")
local CurrentCam = game.Workspace.Camera
local debounceE = false
local debounceClick = false
local isTouchingWindow = false
-- handle touch hit
local function HandleTouch(hit)
if hit:IsA(Player) then
isTouchingWindow = true
print("Touched Window 1")
end
end
-- handle touch ended
local function HandleTouchEnded(hit)
if hit:IsA(Player) then
isTouchingWindow = false
print("Touch Ended Window 1")
end
end
-- call function if touched and end touch
TouchWindow1.Touched:Connect(HandleTouch)
TouchWindow1.TouchEnded:Connect(HandleTouchEnded)
TouchWindow2.Touched:Connect(HandleTouch)
TouchWindow2.TouchEnded:Connect(HandleTouchEnded)
-- handle press of e and make sure you are in a touchwindow part
UIS.InputBegan:Connect(function(input, processed)
if isTouchingWindow and not processed then
local KeyE = UIS:IsKeyDown(Enum.KeyCode.E)
if KeyE and not debounceE then
debounceE = true
-- Perform actions when E key is pressed
-- Toggle the camera focus
if CurrentCam.CameraType == Enum.CameraType.Scriptable then
CurrentCam.CameraType = Enum.CameraType.Custom
CurrentCam.CFrame = CFrame.new() -- Reset camera orientation
else
CurrentCam.CameraType = Enum.CameraType.Scriptable
CurrentCam.CFrame = WindowCam.CFrame
end
wait(0.5) -- Add a debounce delay
debounceE = false
end
end
end)
UIS.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
print("leftclickfuncended")
debounceClick = false
end
end)
UIS.InputBegan:Connect(function(input, processed)
if input.UserInputType == Enum.UserInputType.MouseButton1 and not processed then
print("leftclickfuncstart")
debounceClick = true
wait(0.5) -- Add a debounce delay
debounceClick = false
end
end)
then this is what that does i havent added the serverscript to control the windowcurtains yet
any help would be greatly appreciated i honestly have no idea how to go about doing this
Hey, very good start, I understand the concern and here’s the solution
CollectionService:
Have you ever noticed that if you scroll down all the way to the bottom of a part’s properties they have something called tags and attributes? Well, in this case we want to use the tags.
If you add a tag to each window part called “Window” you can then check all the “Window” tagged parts
for _, window in (CollectionService:GetTagged("Window")) do
window.Touched:Connect(HandleTouch)
window.TouchEnded:Connect(HandleTouchEnded)
end
There’s a lot more stuff you can do with this and I hope you look into it more.
Also, you have this line,
-- boolvalues
local CurtainsClosed1 = WindowConfig.CurtainsClosed1
local CurtainsClosed2 = WindowConfig.CurtainsClosed2
Which might concern you but if you just give an boolean attribute to the window and call it “Closed” to check if that window has an open or closed curtain.
After several hours of coding I have managed to do this
-- clientscript
-- variables
local Player = game.Players.LocalPlayer
local CurtainAttributeChange = game.ReplicatedStorage.CurtainAttributeChange
local CollectionService = game:GetService("CollectionService")
local UIS = game:GetService("UserInputService")
-- get tagged window
local Windows = CollectionService:GetTagged("Window")
for _, Window in pairs(Windows) do -- connect windows to touched functions
Window.Touched:Connect(function(hit) -- if a window tagged part is touched
if hit:IsA(Player) then
print("Window Touched")
WindowTouched = Window
WindowCam = Window:FindFirstChild("WindowCamera")
end
end)
Window.TouchEnded:Connect(function(hit)-- if that touch ended
if hit:IsA(Player) then
print("Window TouchEnded")
WindowTouched = nil
end
end)
end
local Key = UIS:IsKeyDown(Enum.KeyCode.E)
local CurrentCam = game.Workspace.Camera
local Debounce = false
UIS.InputBegan:Connect(function(input)
if UIS:IsKeyDown(Enum.KeyCode.E) and WindowTouched and Debounce ~= true then -- if e pressed and on window then
print("E pressed")
Debounce = true
if CurrentCam.CameraType == Enum.CameraType.Scriptable then -- set camera position
CurrentCam.CameraType = Enum.CameraType.Custom
CurrentCam.CFrame = CFrame.new()
else
CurrentCam.CameraType = Enum.CameraType.Scriptable
CurrentCam.CFrame = WindowCam.CFrame
end
wait(0.5)
Debounce = false
end
end)
UIS.InputBegan:Connect(function(input) -- if leftclick set attribute true
if input.UserInputType == Enum.UserInputType.MouseButton1 and WindowTouched then
print("leftclickstarted")
local AttributeValue = true
CurtainAttributeChange:FireServer(AttributeValue, WindowTouched)-- fire server sending attribute value and windownumber
print("ValueChanged")
end
end)
UIS.InputEnded:Connect(function(input) -- if leftclick ended set attribute false
if input.UserInputType == Enum.UserInputType.MouseButton1 and WindowTouched then
print("leftclickended")
local AttributeValue = false
CurtainAttributeChange:FireServer(AttributeValue, WindowTouched)
print("ValueChanged")
end
end)
-- serverscript
-- variables
local CollectionService = game:GetService("CollectionService")
local Windows = CollectionService:GetTagged("Window")
local CurtainAttributeChange = game.ReplicatedStorage.CurtainAttributeChange
local WindowFolder = game.Workspace.Windows
CurtainAttributeChange.OnServerEvent:Connect(function(AttributeValue, WindowTouched)
WindowTouched:SetAttribute("CurtainsClosed", AttributeValue)-- set attribute value
end)
print("running")
for _, Window in pairs(Windows) do -- for all windows connect to function
print("runningforloop")
Window:GetAttributeChangedSignal("CurtainsClosed"):Connect(function() -- if attribute changed do
print("curtainfunc")
local CurtainsClosed = Window:GetAttribute("CurtainsClosed")
local Curtain1 = Window:FindFirstChild("Curtain1")
local Curtain2 = Window:FindFirstChild("Curtain2")
-- original positions
local OriginPosition1 = Curtain1.CFrame
local OriginPosition2 = Curtain2.CFrame
-- closed positions
local CurtainClosedPosition1 = Window:FindFirstChild("CurtainPosition1").CFrame
local CurtainClosedPosition2 = Window:FindFirstChild("CurtainPosition2").CFrame
if CurtainsClosed == true then -- check if true
print("CurtainClosed")
-- change curtains positions to closed positions
Curtain1.CFrame = CurtainClosedPosition1
Curtain2.CFrame = CurtainClosedPosition2
else -- else must be false
print("CurtianOpen")
-- change curtains positions back to origin
Curtain1.CFrame = OriginPosition1
Curtain2.CFrame = OriginPosition2
end
end)
end
it works almost perfectly except the remote event on server side keeps returning attempt to index boolean with setattribute, but i dont have the brain capacity to fix that right now because its 7 am for me and i havent slept
When you send server events the first parameter is always player
CurtainAttributeChange.OnServerEvent:Connect(function(AttributeValue, WindowTouched)
WindowTouched:SetAttribute("CurtainsClosed", AttributeValue)-- set attribute value
end)
Instead looks like this
CurtainAttributeChange.OnServerEvent:Connect(function(Player, AttributeValue, WindowTouched)
WindowTouched:SetAttribute("CurtainsClosed", AttributeValue)-- set attribute value
end)