@@ -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
3939To 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
124124Add a ``Sprite2D `` node to your scene and set the texture to Godot icon. Attach
125125and 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+
289380Instancing 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