Is it possible to decide which operator to use with a variable?

Godot Version

Godot v4.4

Question

So I have this thing to determine whether a hinge (current node) has mouseover highlighting and can be interacted with based on the angle of the player’s third-person camera relative to it. It uses large Area3Ds, one childed to the parent segment and one to the moving one. It decides whether to treat it as an acute angle (point opposite to the camera needs to only be in one of the areas to make it not clickable) or obtuse (both) by checking if the child segment itself is inside the parent segment’s detection box
func _process(_delta:float)->void:
	cam_approacher[MAIN].global_position=utils.point(
		self,
		cam_playr.global_rotation,
		0.05)
	var good:=[true,true]
	for area in 2: for body in camchecker[area][MAIN].get_overlapping_areas():
		if body==cam_approacher[MAIN]: good[area]=false
	var obtuse:=true
	for body in camchecker[0][MAIN].get_overlapping_bodies():if body==childpanel: obtuse=false;break
	#print("obtuse" if obtuse else "acute")
	clickable=(true if (good[0] or good[1]) else false) if obtuse else (true if (good[0] and good[1]) else false)

TLDR:

how do I get it to decide what operator to use in a line of code depending on a variable’s value (or is it impossible) because something tells me clickable=(true if (good[0] or good[1]) else false) if obtuse else (true if (good[0] and good[1]) else false) is not the best we can do here

Hi,

Ternary operators and if/else statements are made precisely for that, so your code is correct. Or maybe I’m not aware of some existing black magic in GDScript allowing to do what you want, but really I don’t think so.


However, your line is indeed a bit harsh to read, but, you can simplify the expressions:

(true if (good[0] or good[1]) else false) => (good[0] or good[1])
(true if (good[0] and good[1]) else false) => (good[0] and good[1])

good[0] and good[1] both being booleans, you can use them directly as such, instead of checking them to return other booleans.

Which will result in clickable=(good[0] or good[1]) if obtuse else (good[0] and good[1]) that’s definitely more readable.


Alternatively, you could use an if/else structure:

if obtuse:
    clickable = good[0] and good[1]
else:
    clickable = good[0] or good[1]

I know it’s more lines of code, but if it’s more readable, I do believe it’s worth it.


Last option, you could define two variables:

var both_good: bool = good[0] and good[1]
var any_good: bool = good[0] or good[1]
clickable = any_good if obtuse else both_good

which, to be honest, I’m not a big fan of, but, maybe you’ll enjoy it more that I do as it would make the code more readable, with one less line that the if/else version.

2 Likes