How to drag and drop data in Editor

Editor data structure

Editor tell other nodes what data is going to be passed through some structs that are
are converted to dictionaries.

These structs usually have this format:

{type, value, origin}
  • type identifies which kind of data is being passed.
  • value is the literal value.
  • origin usually contains a path from where the data is being gathered, but usually is not a reliable value and can only be used as reference.

You can get these structures or create them to handle or pass data from/to editor in your EditorPlugin and @tool projects.

for files from Editor FileSystem

{ 
  "type": "files", 
  "files": ["res://path/to/your/resource.tres"], 
  "from": @@6431:<Tree#559234967434>
}
  • type is "files", referring to String (path) being drag from EditorFileSystem. You can’t change that.

  • The file path is absolute to project folder res://, and all dragged file paths are passed in "files" array. It doesn’t try to load the actual resource.

Note: Some plugins in the future may (or may not) add extra “virtual” directories like user://, but at the version of writing this guide (Godot 4) this is not common, so path is always from res:// when is the editor instance who is giving the data.

for nodes from SceneEditor

{
  "type": "nodes", 
  "nodes": [^"/root/@@very/@@long/@@editor/@@node/@@paths/YourNode"]
}
  • type is "nodes", referring to Node being drag from SceneEditor tree, not viewport. You can’t change that.

  • Each node path is passed in "nodes" array. Objects are not passed on this struct, but since these are supposed to be always a full path, using get_node() should not raise any error and return the actual node being drag.

If you get the node reference, never free these nodes. Other objects may rely on these references and can lead memory leaks and editor crash.

for Object properties from EditorInspector

{
  "type": "obj_property",
  "object": <ObjectClassName#ObjectID>,
  "property": &"property_name",
  "value": <Variant>
}
  • type is "obj_property", referring to an actual property from EditorInspector being drag. You can’t change that.

  • Object reference is passed in "object" key, no matter what kind of object is (Node or Resource usually). Do not free the object.

  • It’s current value (at the moment of drag) and the dragged property are passed in value and property respectively.

for resources from EditorProperty

{
  "type": "resource",
  "resource": <ResourceClassName#ObjectID>, 
  "from": @@---:<Node#ObjectID>
}

Is a rare case, but you can grab the resource object and not the property pointing to the resource when you grab it from EditorResourcePicker

  • type is “resource”, referring to an actual Resource object being drag. You can’t change that.

  • resource key holds the actual Resource object.

  • from can refer to the node that holds the data.


How to drag and drop for editor

If you want to be able to handle arbitrary data that is being drag in editor (like files or nodes) you must know how Godot handles drag and drop with Control nodes using _can_drop_data and _drop_data.

To be able to simulate the data that editor wants, return the mentioned structures on _get_drag_data, editor will handle it without problems.

Extra links

See this documentation page for more information about drag and drop:

This is an updated version of this gist.

1 Like