Toggling properties without using ifs

sometimes, long codes are ugly. just look at this normal door code:

--normal
script.Parent.ClickDetector.MouseClick:Connect(function()
	if script.Parent.Transparency == 0 then
		script.Parent.Transparency = 1
		script.Parent.CanCollide = false
	else
		script.Parent.Transparency = 0
		script.Parent.CanCollide = true
	end
end)

it works, but you probably dont wanna write that, you want something shorter

so, lets just clear that code.

script.Parent.ClickDetector.MouseClick:Connect(function()
	
end)

now, how do we make a toggle a property without ifs? lets just think of an method.

okay, so to toggle the cancollide we will use the following method:

print(true) -- true
print(not true) -- false
print(false) -- false
print(not false) -- true

get it? so this snippet would toggle the cancollide property:

script.Parent.CanCollide = not script.Parent.CanCollide

lets add that to our code

script.Parent.ClickDetector.MouseClick:Connect(function()
	script.Parent.CanCollide = not script.Parent.CanCollide
	
end)

now, what about transparency? not script.Parent.Transparency would not work, so this one is more complex but im pretty sure you will get the method.

print(1 and 0 or 1) -- 0

that was creepy, but it prints 0, so now what about it being 0?

print(0 and 0 or 1)

its still, 0, not toggleable, so we will change the code a bit

print(1 == 1 and 0 or 1) -- 0
print(0 == 1 and 0 or 1) -- 1

it worked! now this is what it should be:

script.Parent.Transparency = (script.Parent.Transparency == 1 and 0 or 1)

a bit difficult right? but its shorter, so now your new cleaner code should look like this:

script.Parent.ClickDetector.MouseClick:Connect(function()
	script.Parent.CanCollide = not script.Parent.CanCollide
	script.Parent.Transparency = (script.Parent.Transparency == 1 and 0 or 1)
end)

and yes, it does work.

now what if i want to toggle colors?
well dont return to if for that, you could do the same method of the transparency thing we just did.

script.Parent.BrickColor = (script.Parent.BrickColor == BrickColor.Red() and BrickColor.Green() or BrickColor.Red())

longer but still shorter and better than if.

now if youre making an actual opening door, you could do something similar like this

script.Parent.ClickDetector.MouseClick:Connect(function()
	script.Parent.ClickDetector.MaxActivationDistance = 0 -- because they can break it by spam-clicking
	game:GetService("TweenService"):Create(script.Parent,TweenInfo.new(2),{Position=(script.Parent.Position == Vector3.new(-2.7, 6.05, -34.2) and Vector3.new(-2.7, 6.05, -11.4) or Vector3.new(-2.7, 6.05, -34.2))}):Play()
        task.wait(5)
	script.Parent.ClickDetector.MaxActivationDistance = 32
end)

yeah reading it just puts salt in your eyes but i hope you get it

now you know how to simplify toggling codes, this could save time.

ifs could be used for something else, but if youre toggling something then this method is better than if

i know this was short

if you’re confused or want to send feedbacks, go on.

6 Likes

Obligatory mention that less code does not necessarily equal better, cleaner or more readable code.

A caution about using fake ternary: if the operand on the left of the and is falsy then it will evaluate to the operand on the or. If you have behaviour where you’re expecting condition and false or true this will not evaluate the way you want it to. If-then-else assignments should be what you use here as if condition then false else true, this way your assignment isn’t decided by the operands but instead solely by the condition that you’re trying to check.

Remember that BrickColors are objects with properties. You don’t need to construct a new BrickColor just for simple comparisons, just check the properties if you need to reference them. There’s many ways to go about this but as an example:

local color = if Part.BrickColor.Name == "Bright red" then "Bright green" else "Bright red"
Part.BrickColor = BrickColor.new(color)

As for the door example, it’s sort of poor altogether. There are many better options you could use for this instead — debounces rather than MaxActivationDistance (a client can set it back and then spam click it thus rendering your intentions moot), a state variable to determine the door’s open state and therefore also the position it should be in and using CFrame as a goal instead of Position (the latter does overlap checks so if your door is in an enclosed space it will not open until the current tween step has a position that does not overlap another part).

4 Likes

Thank you for your feedback but would you make aggressive ifs just to make a door or do ternary? It’s shorter, but ik it’s less readable and harder to understand, but it’s worth saving time

What do you mean by “aggressive ifs”? I mentioned using a state variable.

local DOOR_OPEN_CFRAME = CFrame.new()
local DOOR_CLOSED_CFRAME = CFrame.new()

local doorOpen = false
local debounce = false

ClickDetector.MouseClick:Connect(function (player)
    if debounce then return end

    debounce = true
    local previousActiveDistance = ClickDetector.MaxActivationDistance
    ClickDetector.MaxActivationDistance = 0

    doorOpen = not doorOpen

    local tween = TweenService:Create(Door, TweenInfo.new(2), {
        CFrame = if doorOpen then DOOR_OPEN_CFRAME else DOOR_CLOSED_CFRAME
    })
    tween:Play()
    tween.Completed:Wait() -- Or task.wait if the timeout has to be longer

    debounce = false
    ClickDetector.MaxActivationDistance = previousActiveDistance
end)

Saving time and convenience is not an excuse to write poor, unmaintainable, unreadable code. That just saves you time now, it doesn’t help you later. This is an especially detrimental way of thinking if you’re working on a serious project with higher technical and community demands; fast iteration is as important as having code that is maintainable.

You will thank yourself later when you spend less time working through technical debt and more time working on features with a solid codebase adopting good habits. Development speed is as important as having proper code that won’t give you a headache later on when you need to improve it.

3 Likes

I totally agree with you, but if you expect to not edit it later we could use some speed up.

You could also do:

local t = script.Parent.Transparency
script.Parent.Transparency = 1 - t
2 Likes

Nice