Skip to content

Commit b9f8f9e

Browse files
authored
Merge pull request godotengine#8471 from Calinou/running-code-in-the-editor-editorscript
Document using EditorScript in Running code in the editor
2 parents 9aba4a0 + 48596bc commit b9f8f9e

File tree

2 files changed

+97
-6
lines changed

2 files changed

+97
-6
lines changed
4.73 KB
Loading

tutorials/plugins/running_code_in_the_editor.rst

Lines changed: 97 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ use cases:
3333
:ref:`Node.queue_free<class_Node_method_queue_free>`, as it can cause
3434
crashes if you free a node while the editor runs logic involving it.
3535

36-
How to use it
37-
-------------
36+
How to use ``@tool``
37+
--------------------
3838

3939
To turn a script into a tool, add the ``@tool`` annotation at the top of your code.
4040

@@ -118,8 +118,8 @@ Here is how a ``_process()`` function might look for you:
118118
behavior from the super class. Therefore the extending script should also
119119
specify the ``@tool`` annotation.
120120

121-
Try it out
122-
-----------
121+
Try ``@tool`` out
122+
-----------------
123123

124124
Add a ``Sprite2D`` node to your scene and set the texture to Godot icon. Attach
125125
and open a script, and change it to this:
@@ -286,6 +286,97 @@ By default, the warning only updates when closing and reopening the scene.
286286
# Returning an empty array means "no warning".
287287
return warnings
288288

289+
Running one-off scripts using EditorScript
290+
------------------------------------------
291+
292+
Sometimes, you need to run code just one time to automate a certain task that is
293+
not available in the editor out of the box. Some examples might be:
294+
295+
- Use as a playground for GDScript or C# scripting without having to run a project.
296+
``print()`` output is displayed in the editor Output panel.
297+
- Scale all light nodes in the currently edited scene, as you noticed your level
298+
ends up looking too dark or too bright after placing lights where desired.
299+
- Replace nodes that were copy-pasted with scene instances to make them easier
300+
to modify later.
301+
302+
This is available in Godot by extending :ref:`class_EditorScript` in a script.
303+
This provides a way to run individual scripts in the editor without having to
304+
create an editor plugin.
305+
306+
To create an EditorScript, right-click a folder or empty space in the FileSystem
307+
dock then choose **New > Script...**. In the script creation dialog, click the
308+
tree icon to choose an object to extend from (or enter ``EditorScript`` directly
309+
in the field on the left, though note this is case-sensitive):
310+
311+
.. figure:: img/running_code_in_the_editor_creating_editor_script.webp
312+
:align: center
313+
:alt: Creating an editor script in the script editor creation dialog
314+
315+
Creating an editor script in the script editor creation dialog
316+
317+
This will automatically select a script template that is suited for
318+
EditorScripts, with a ``_run()`` method already inserted:
319+
320+
::
321+
322+
@tool
323+
extends EditorScript
324+
325+
# Called when the script is executed (using File -> Run in Script Editor).
326+
func _run():
327+
pass
328+
329+
This ``_run()`` method is executed when you use **File > Run** or the keyboard
330+
shortcut :kbd:`Ctrl + Shift + X` while the EditorScript is the currently open
331+
script in the script editor. This keyboard shortcut is only effective when
332+
currently focused on the script editor.
333+
334+
Scripts that extend EditorScript must be ``@tool`` scripts to function.
335+
336+
.. warning::
337+
338+
EditorScripts have no undo/redo functionality, so **make sure to save your
339+
scene before running one** if the script is designed to modify any data.
340+
341+
To access nodes in the currently edited scene, use the
342+
:ref:`EditorScript.get_scene <class_EditorScript_method_get_scene>` method which
343+
returns the root Node of the currently edited scene. Here's an example that
344+
recursively gets all nodes in the currently edited scene and doubles the range
345+
of all OmniLight3D nodes:
346+
347+
::
348+
349+
@tool
350+
extends EditorScript
351+
352+
func _run():
353+
for node in get_all_children(get_scene()):
354+
if node is OmniLight3D:
355+
# Don't operate on instanced subscene children, as changes are lost
356+
# when reloading the scene.
357+
# See the "Instancing scenes" section below for a description of `owner`.
358+
var is_instanced_subscene_child = node != get_scene() and node.owner != get_scene()
359+
if not is_instanced_subscene_child:
360+
node.omni_range *= 2.0
361+
362+
# This function is recursive: it calls itself to get lower levels of child nodes as needed.
363+
# `children_acc` is the accumulator parameter that allows this function to work.
364+
# It should be left to its default value when you call this function directly.
365+
func get_all_children(in_node, children_acc = []):
366+
children_acc.push_back(in_node)
367+
for child in in_node.get_children():
368+
children_acc = get_all_children(child, children_acc)
369+
370+
return children_acc
371+
372+
.. tip::
373+
374+
You can change the currently edited scene at the top of the editor even
375+
while the Script view is open. This will affect the return value of
376+
:ref:`EditorScript.get_scene <class_EditorScript_method_get_scene>`, so make
377+
sure you've selected the scene you intend to iterate upon before running
378+
the script.
379+
289380
Instancing scenes
290381
-----------------
291382

@@ -308,7 +399,7 @@ If you are using ``@tool``:
308399

309400
# The line below is required to make the node visible in the Scene tree dock
310401
# and persist changes made by the tool script to the saved scene file.
311-
node.set_owner(get_tree().edited_scene_root)
402+
node.owner = get_tree().edited_scene_root
312403

313404
.. code-tab:: csharp
314405

@@ -335,7 +426,7 @@ If you are using :ref:`EditorScript<class_EditorScript>`:
335426

336427
# The line below is required to make the node visible in the Scene tree dock
337428
# and persist changes made by the tool script to the saved scene file.
338-
node.set_owner(get_scene())
429+
node.owner = get_scene()
339430

340431
.. code-tab:: csharp
341432

0 commit comments

Comments
 (0)