Godot 3 to 4 rename
VisualShaderNodeScalarSwitch in Godot 4: it is VisualShaderNodeSwitch now
VisualShaderNodeScalarSwitch is VisualShaderNodeSwitch in Godot 4.7.2: one switch node, whose op_type picks float, int, uint, a 2D, 3D or 4D vector, a boolean or a transform. Set to floats, Godot generated no branch for it: the choice became a mix() with the condition as a float.
What Godot prints
A Godot 3 script that builds a float switch node for a visual shader in code.
extends Node
func _ready():
var shader = VisualShader.new()
var pick = VisualShaderNodeScalarSwitch.new()
shader.add_node(VisualShader.TYPE_FRAGMENT, pick, Vector2(0, 0), 2)
print(shader.get_code())
SCRIPT ERROR: Parse Error: Identifier "VisualShaderNodeScalarSwitch" not declared in the current scope. Did you mean to use "VisualShaderNodeSwitch"?
at: GDScript::reload (res://answers/visualshadernodescalarswitch-in-godot-4/repro.gd:5)
ERROR: Failed to load script "res://answers/visualshadernodescalarswitch-in-godot-4/repro.gd" with error "Parse error".
at: load (modules/gdscript/gdscript_resource_format.cpp:46)The fix
One VisualShaderNodeSwitch, set to floats with op_type, its condition taken from a boolean parameter and its result sent to the fragment output. The fix prints the lines of generated shader code that make the choice.
extends Node
func _ready() -> void:
var shader := VisualShader.new()
var lit := VisualShaderNodeBooleanParameter.new()
lit.parameter_name = "lit"
shader.add_node(VisualShader.TYPE_FRAGMENT, lit, Vector2(0, 0), 2)
var pick := VisualShaderNodeSwitch.new()
pick.op_type = VisualShaderNodeSwitch.OP_TYPE_FLOAT
shader.add_node(VisualShader.TYPE_FRAGMENT, pick, Vector2(200, 0), 3)
shader.connect_nodes(VisualShader.TYPE_FRAGMENT, 2, 0, 3, 0)
shader.connect_nodes(VisualShader.TYPE_FRAGMENT, 3, 0, 0, 0)
var code := shader.get_code()
var start := code.find("// Switch:3")
print(code.substr(start, code.find("\n\n", start) - start) if start >= 0 else code)
// Switch:3
float n_in3p1 = 1.00000;
float n_in3p2 = 0.00000;
n_out3p0 = mix(n_in3p2, n_in3p1, float(n_out2p0));Why it happens
GDScript's analyzer resolves every identifier when the script loads. VisualShaderNodeScalarSwitch is not a class in Godot 4.7.2, so the script fails to parse and Godot does not load it. The editor build adds the new name from Godot's 3 to 4 rename table: Did you mean to use "VisualShaderNodeSwitch"?
VisualShaderNodeSwitch returns one of two values of its op_type, depending on whether its boolean input is true or false. op_type is one of OP_TYPE_FLOAT, OP_TYPE_INT, OP_TYPE_UINT, OP_TYPE_VECTOR_2D, OP_TYPE_VECTOR_3D, OP_TYPE_VECTOR_4D, OP_TYPE_BOOLEAN and OP_TYPE_TRANSFORM.
In the code Godot generated, the two value inputs left unconnected kept their defaults, 1.0 for true and 0.0 for false, and the result is mix(false_value, true_value, float(condition)), with no if statement.
Sources
Run on Godot 4.7.2, .