Exposing Properties in a Editor Plugin to be able to modify them in the Editor

Godot Version

4.6.2.stable.official [71f334935]

Question

Okay, I admit it I’m lost, and probably an idiot or both, not uncommon :slight_smile: Not having created tool scripts or plugins in the past I have no idea what I’m doing.

I have an editor plugin script which is used for syntax highlighting, we all know that by now. I want to be able to expose the colours for each element so each dev can set their own preferences. I have the following for each colour in the script, the script is working properly, but I have no idea where to find them in the editor or even if I’m doing it correctly, any help would be appreciated.

	@export var comments: Color = Color.MEDIUM_SEA_GREEN:
		set(new_comments):
			comments = new_comments

I tried using metadata and though that worked it is lost between sessions, apparently a known bug that meta data is not saved when added in the editor or attached to a script.

I’d just create a static helper file called like syntax_color.gd

class_name SyntaxColor extends Node

@export var comments: Color = Color.MEDIUM_SEA_GREEN

Create a scene with a single node in it, assign the script to it, and save it as syntax_color.tscn.

Then from lines 45-48 of your assembly_syntax_highlighter.gd change line 47:

		# Full Line Comments just return green
		if codeLine.strip_edges().begins_with(";"):
			color_map[0] = { "color": SyntaxColor.comments }
			return color_map

Then anyone can just open the syntax_color.tscn file in the addons/assembly_syntax_highlighter folder and change the values in the inspector.

1 Like

Okay, close but still have the following error:

Cannot find member “default” in base “SyntaxColor”

The code as you suggested I hope, script is called syntax_color.gd and scene syntax_color.tscn

class_name SyntaxColor extends Node

@export var default: Color  = Color.LIGHT_GRAY
@export var comments: Color = Color.MEDIUM_SEA_GREEN
@export var labels: Color = Color.GOLD
@export var reserved_words: Color = Color.SKY_BLUE
@export var compiler_directives: Color = Color.CORAL
@export var constants: Color = Color.GOLDENROD
@export var numbers: Color = Color.AQUAMARINE
@export var registers: Color = Color.GREEN_YELLOW
@export var quoted_text: Color = Color.MEDIUM_PURPLE

The class name SyntaxColor is certainly resolved just can see any of its variables, so none of the colours are available. If I open the scene in the editor then yes all the colours are there, so one step closer.

Just realized that won’t work, because you have to declare them static and you can’t do that with export variables. This is where Autoloads come in handy.

  1. Remove the class name from your script (because Autoloads can’t have class names).
  2. Add the .tscn file as an Autoload.

That should work, and then you can add the file as an Autoload as part of activating the plugin.

1 Like

You must think me so dumb, even adding the scene manually as an autoload doesn’t work. And I’ve not been able to figure out how to load it as part of the plugin. :frowning: Give me assembly any day.. Not sure what I’m doing wrong.. Sorry, though this is how we learn..

In this case does it need to be a tool script and extend from EditorPlugin or Node.. ???

Not at all. I remember how daunting Godot plugins were when I started, and I’ve been programming professionally for 30 years. It’s just learning a new skill. :slight_smile:

I will try to do a prototype for you tomorrow if you can’t get it working, but I’m winding down now.

In the meantime, here’s how I do it in my Controller Plugin: dragonforge-camera-3d/addons/dragonforge_controller/plugin.gd at main · dragonforge-dev/dragonforge-camera-3d · GitHub

@tool
extends EditorPlugin

const AUTOLOAD_GAMEPAD = "Gamepad"
const AUTOLOAD_MOUSE = "Mouse"
const AUTOLOAD_KEYBOARD = "Keyboard"
const AUTOLOAD_CONTROLLER = "Controller"


func _enable_plugin() -> void:
	add_autoload_singleton(AUTOLOAD_GAMEPAD, "res://addons/dragonforge_controller/gamepad.tscn")
	add_autoload_singleton(AUTOLOAD_MOUSE, "res://addons/dragonforge_controller/mouse.tscn")
	add_autoload_singleton(AUTOLOAD_KEYBOARD, "res://addons/dragonforge_controller/keyboard.tscn")
	add_autoload_singleton(AUTOLOAD_CONTROLLER, "res://addons/dragonforge_controller/controller.tscn")


func _disable_plugin() -> void:
	remove_autoload_singleton(AUTOLOAD_CONTROLLER)
	remove_autoload_singleton(AUTOLOAD_KEYBOARD)
	remove_autoload_singleton(AUTOLOAD_MOUSE)
	remove_autoload_singleton(AUTOLOAD_GAMEPAD)
1 Like

Ahh I missed the const bit so I’ll give that a type. Yes, admitting we don’t know something is often the only way forward. Take guts sometimes to admit it and ask for help..

1 Like

Also, UIDs should work instead of hardcoded paths. I just thought of that.

1 Like

Well no go, not sure what the issue is. Would love to see a working example of how to do it, but only if you have time. It’s odd I can load and set all the colours as meta_data on the script during runtime and even recall and use them. You just can see the meta_data when added through a script, a bug apparently. Would be my preferred method.. Many thanks

class_name SyntaxColor extends Resource

@export var default: Color = Color.LIGHT_GRAY
#etc

Create the resource object in the inspector and save it to your plugin folder.
Load the resource in _enable_plugin() using ResourceLoader

1 Like

Thank you, Thank you, Thank you, it works. Easy when you know how. And I’ve learned something today so a bonus. Always a good day when that happens. Now to add hot reloading to the resource if changed, while editing.

Thanks to both you @normalized and @dragonforge-dev for your tireless assistance.

1 Like

Just found out I don’t need to hot reload the resource for the syntax colours it’s automatic. Very cool. :slight_smile: