Allow exporting variables of type Variant
Inspired by https://github.com/godotengine/godot-proposals/issues/9269 Closes https://github.com/godotengine/godot-proposals/issues/9368
This PR allows for exporting variables of type Variant. They show a property editor similar to what Array and Dictionary are using:
https://github.com/godotengine/godot/assets/2223172/b5aa8fdc-f107-44fd-b79a-bc46658857de
This allows for nice flexibility, where you can change not only the variable, but also its value and allows for better customization.
example plugin for "tri-state bool"
@tool
extends EditorPlugin
var state3 := TriStateBoolInspectorPlugin.new()
func _enter_tree() -> void:
add_inspector_plugin(state3)
func _exit_tree() -> void:
remove_inspector_plugin(state3)
class TriStateBoolInspectorPlugin extends EditorInspectorPlugin:
func _can_handle(object: Object) -> bool:
return true
func _parse_property(object: Object, type: Variant.Type, name: String, hint_type: PropertyHint, hint_string: String, usage_flags: int, wide: bool) -> bool:
if type == TYPE_NIL and hint_string == "3bool":
add_property_editor(name, TriStateBoolEditor.new())
return true
return false
class TriStateBoolEditor extends EditorProperty:
var button: TriStateCheckbox
func _init() -> void:
button = TriStateCheckbox.new()
add_child(button)
button.pressed.connect(func(): get_edited_object().set(get_edited_property(), button.state))
func _update_property() -> void:
button.state = get_edited_object().get(get_edited_property())
class TriStateCheckbox extends Button:
const STATES = [null, false, true]
var textures: Array[Texture2D]
var state: Variant:
set(s):
state = s
icon = textures[STATES.find(state)]
func _init() -> void:
size_flags_horizontal = SIZE_SHRINK_BEGIN
for color in [Color.RED, Color.GREEN, Color.BLUE]:
var gradient := Gradient.new()
gradient.remove_point(1)
gradient.colors = [color]
var texture := GradientTexture2D.new()
texture.gradient = gradient
texture.width = 16
texture.height = 16
textures.append(texture)
func _pressed() -> void:
for i in STATES.size():
if STATES[i] == state:
state = STATES[(i + 1) % STATES.size()]
break
Example usage:
@export_custom(0, "3bool") var boolean_hat_trick
https://github.com/godotengine/godot/assets/2223172/1aab2534-ff73-4f29-aa85-0b7792b6319f
(the text is updated with _process().
- See also #33080.
I wanted to salvage/re-implement it. I think this should work like Dictionary key/value editor, the user could select the type first, then the value.
I thought about that too, but opted for a simpler solution (as the goal was customizability itself). I can rework this into the type dropdown widget if that's better.
Ok reworked
https://github.com/godotengine/godot/assets/2223172/b5aa8fdc-f107-44fd-b79a-bc46658857de