I am currently creating a puzzle game where you move boxes on squares to open doors, but for now I'm creating a door which you click to open. Here is my code:
doorPart = script.Parent clickDetector = doorPart.ClickDetector doorOpen = false clickDetector.MouseClick:connect(function() if (doorOpen == false) then doorOpen = true else if (doorOpen == true) then doorOpen = false end end end) if (doorOpen == true) then doorPart.CanCollide = false doorPart.Transparency = .5 else if(doorOpen == false) then doorPart.CanCollide = true doorPart.Transparency = 0 end end
It used to be one big if, where it would change the CanCollide, Transparency, and doorOpen variable all at once, but that didn't work so I attempted to make 2 seperate conditional statements.
Help is greatly appreciated! Thanks!
:)
The problem is that your code below doesn't run when you click the ClickDetector
. It only runs once when the game starts. To fix this, you can just wrap the part of your code in a while loop
.
Eg
doorPart = script.Parent clickDetector = doorPart.ClickDetector doorOpen = false clickDetector.MouseClick:connect(function() if (doorOpen == false) then doorOpen = true else if (doorOpen == true) then doorOpen = false end end end) while true do wait() if (doorOpen == true) then doorPart.CanCollide = false doorPart.Transparency = .5 else if(doorOpen == false) then doorPart.CanCollide = true doorPart.Transparency = 0 end end end
This code will check the doorOpen
value every 1/30th of a second.
Try something like this:
local dp = script.Parent local cd = dp.ClickDetector do = false cd.MouseClick:Connect(function() if do then dp.CanCollide = false dp.Transparency = 0 do = false elseif do = false then dp.CanCollide = true dp.Transparency = true do = true end end)
Sorry for any mistakes, I'm on mobile right now.
The correct script:
doorPart = script.Parent clickDetector = doorPart.ClickDetector doorOpen = false clickDetector.MouseClick:connect(function() if doorOpen == false then doorOpen = true elseif doorOpen == true then doorOpen = false end end) while wait() do if doorOpen == true then doorPart.CanCollide = false doorPart.Transparency = .5 elseif doorOpen == false then doorPart.CanCollide = true doorPart.Transparency = 0 end end
First off, you don't need those odd parenthesis when doing an if statement. Second off, for elseif statements, you don't need an extra 'end' because it's still part of the if statement that it's under (hope that makes sense). Third off, you need to do a "while wait() do" loop for your if statement, as it won't continuously check like a built in function (a "while wait() do" loop is an effective way to check consistently and keep the script from crashing),
Another way to do this, without having loops, is to put all of that code inside of the clickDetector.mouseClick function. Here is how I would script a simple door:
-- Stuff local doorPart = script.Parent local clickDetector = doorPart.ClickDetector -- Vars local doorOpen = false -- Internal Functions local function ToggleDoor() if doorOpen then -- Close the door doorPart.CanCollide = true doorPart.Transparency = 0 else -- Open the door doorPart.CanCollide = false doorPart.Transparency = 0.5 end end) -- Click detector clickDetector.MouseClick:Connect(function() doorOpen = not doorOpen -- Set the doorOpen to whatever it's not. ToggleDoor() -- Apply the changes. Also, if it's your preference, you can just copy the function's code and re-paste it here if you don't want another separate function. end)
This is better, because if you decide to duplicate the door for other parts of your game, you won't have many loops constantly running and checking for door's state. (If you want to be even more efficient you could use CollectionService tags and then you can have a single script control all doors.)
Hope this helps!