Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

プラグインの作成

プラグインについて

プラグインは、便利なツールを使用してエディタを拡張する優れた方法です。エディタをリロードしなくても、GDScriptと標準シーンで完全に作成できます。モジュールとは異なり、C++コードを作成したり、エンジンを再コンパイルしたりする必要はありません。これによりプラグインのパワフルさが低下しますが、プラグインでできることはまだたくさんあります。プラグインは、エディタ機能を追加するスクリプトを使用して作成されることを除いて、すでに作成できるシーンに似ていることに注意してください。

This tutorial will guide you through the creation of two plugins so you can understand how they work and be able to develop your own. The first is a custom node that you can add to any scene in the project, and the other is a custom dock added to the editor.

プラグインの作成

開始する前に、必要な場所に新しい空のプロジェクトを作成します。これは、プラグインを開発およびテストするためのベースとして機能します。

エディタが新しいプラグインを識別するために最初に必要なことは、設定用の plugin.cfg と機能を備えたツールスクリプトの2つのファイルを作成することです。 プラグインには、プロジェクトフォルダ内に addons/plugin_name のような標準パスがあります。Godotは、これらのファイルを生成し、必要な場所に配置するためのダイアログを提供します。

In the main toolbar, click the Project dropdown. Then click Project Settings.... Go to the Plugins tab and then click on the Create New Plugin button in the top-right.

次のようなダイアログが表示されます:

../../../_images/making_plugins-create_plugin_dialog.webp

各フィールドのプレースホルダーテキストは、プラグインによるファイルの作成と構成ファイルの値にどのように影響するかを説明しています。

To continue with the example, use the following values:

Plugin Name: My Custom Node
Subfolder: my_custom_node
Description: A custom node made to extend the Godot Engine.
Author: Your Name Here
Version: 1.0.0
Language: GDScript
Script Name: custom_node.gd
Activate now: No

警告

Unchecking the Activate now? option in C# is always required because, like every other C# script, the EditorPlugin script needs to be compiled which requires building the project. After building the project the plugin can be enabled in the Plugins tab of Project Settings.

次のようなディレクトリ構造になるはずです:

../../../_images/making_plugins-my_custom_mode_folder.webp

plugin.cfg is an INI file with metadata about your plugin. The name and description help people understand what it does. Your name helps you get properly credited for your work. The version number helps others know if they have an outdated version; if you are unsure on how to come up with the version number, check out Semantic Versioning. The main script file will instruct Godot what your plugin does in the editor once it is active.

スクリプトファイル

Upon creation of the plugin, the dialog will automatically open the EditorPlugin script for you. The script has two requirements that you cannot change: it must be a @tool script, or else it will not load properly in the editor, and it must inherit from EditorPlugin.

警告

EditorPluginスクリプトの他にも、プラグインが使用する全てのGDScriptは必ず*toolでもある*必要があります。 @tool がない全てのGDScriptは、エディタから使われる際に空のファイルのようにふるまいます!

It's important to deal with initialization and clean-up of resources. A good practice is to use the virtual function _enter_tree() to initialize your plugin and _exit_tree() to clean it up. Thankfully, the dialog generates these callbacks for you. Your script should look something like this:

@tool
extends EditorPlugin


func _enter_tree():
    # Initialization of the plugin goes here.
    pass


func _exit_tree():
    # Clean-up of the plugin goes here.
    pass

これは、新しいプラグインを作成するときに使用するのに適したテンプレートです。

カスタム ノード

再利用可能なカスタムシーンやコントロールなど、多くのノードで特定の動作が必要な場合があります。 インスタンス化は多くの場合に役立ちますが、多くのプロジェクトでインスタンス化を使用している場合は特に、面倒な場合があります。 これに対する適切な解決策は、カスタムの動作を持つノードを追加するプラグインを作成することです。

警告

Nodes added via an EditorPlugin are "CustomType" nodes. While they work with any scripting language, they have fewer features than the Script Class system. If you are writing GDScript or NativeScript, we recommend using Script Classes instead.

To create a new node type, you can use the function add_custom_type() from the EditorPlugin class. This function can add new types to the editor (nodes or resources). However, before you can create the type, you need a script that will act as the logic for the type. While that script doesn't have to use the @tool annotation, it can be added so the script runs in the editor.

For this tutorial, we'll create a button that prints a message when clicked. For that, we'll need a script that extends from Button. It could also extend BaseButton if you prefer:

@tool
extends Button


func _enter_tree():
    pressed.connect(clicked)


func clicked():
    print("You clicked me!")

That's it for our basic button. You can save this as my_button.gd inside the plugin folder. You'll also need a 16×16 icon to show in the scene tree. If you don't have one, you can grab the default one from the engine and save it in your addons/my_custom_node folder as icon.png, or use the default Godot logo (preload("res://icon.svg")).

Tip

SVG images that are used as custom node icons should have the Editor > Scale With Editor Scale and Editor > Convert Colors With Editor Theme import options enabled. This allows icons to follow the editor's scale and theming settings if the icons are designed with the same color palette as Godot's own icons.

../../../_images/making_plugins-custom_node_icon.png

次に、**Nodeを新規作成 ** ダイアログに表示されるように、カスタムタイプとして追加する必要があります。そのためには、custom_node.gd スクリプトを次のように変更します:

@tool
extends EditorPlugin


func _enter_tree():
    # Initialization of the plugin goes here.
    # Add the new type with a name, a parent type, a script and an icon.
    add_custom_type("MyButton", "Button", preload("my_button.gd"), preload("icon.png"))


func _exit_tree():
    # Clean-up of the plugin goes here.
    # Always remember to remove it from the engine when deactivated.
    remove_custom_type("MyButton")

これが完了すると、プラグインは プロジェクト設定 のプラグインリストですでに使用可能になっているはずなので、Checking the results で説明されているようにアクティブにします。

次に、新しいノードを追加して試してください:

../../../_images/making_plugins-custom_node_create.webp

ノードを追加すると、作成したスクリプトが既に接続されていることがわかります。 ボタンにテキストを設定し、シーンを保存して実行します。 ボタンをクリックすると、コンソールにテキストが表示されます:

../../../_images/making_plugins-custom_node_console.webp

カスタムドック

場合によっては、エディタを拡張し、常に使用可能なツールを追加する必要があります。簡単な方法は、新しいドックにプラグインを追加することです。ドックはコントロールに基づいた単なるシーンであるため、通常のGUIシーンと同様の方法で作成されます。

カスタムドックの作成は、カスタムノードのように行われます。addons/my_custom_dock フォルダに新しい plugin.cfg ファイルを作成し、次のコンテンツを追加します:

[plugin]

name="My Custom Dock"
description="A custom dock made so I can learn how to make plugins."
author="Your Name Here"
version="1.0"
script="custom_dock.gd"

に、同じフォルダにスクリプト custom_dock.gd を作成します。良いスタートを切るために、:ref:`前に見たテンプレート <doc_making_plugins_template_code> ` を入力してください。

新しいカスタムドックを追加しようとしているので、ドックのコンテンツを作成する必要があります。これは、標準のGodotシーンに他なりません。エディタで新しいシーンを作成し、編集するだけです。

エディタドックの場合、ルートノードは 必ず Control またはその子クラスでなければなりません。このチュートリアルでは、1つのボタンを作成できます。ルートノードの名前は、ドックタブに表示される名前でもあるため、必ず短くわかりやすい名前を付けてください。また、ボタンにテキストを追加することを忘れないでください。

../../../_images/making_plugins-my_custom_dock_scene.webp

このシーンを my_dock.tscn として保存します。次に、作成したシーンを取得し、エディタでドックとして追加する必要があります。このために、EditorPlugin クラスの関数 add_control_to_dock() を使用できます。

ドックの位置を選択し、追加するコントロール(作成したばかりのシーン)を定義する必要があります。プラグインが非アクティブになったら、ドックを削除する ことを忘れないでください。 スクリプトは次のようになります:

@tool
extends EditorPlugin


# A class member to hold the dock during the plugin life cycle.
var dock


func _enter_tree():
    # Initialization of the plugin goes here.
    # Load the dock scene and instantiate it.
    dock = preload("res://addons/my_custom_dock/my_dock.tscn").instantiate()

    # Add the loaded scene to the docks.
    add_control_to_dock(DOCK_SLOT_LEFT_UL, dock)
    # Note that LEFT_UL means the left of the editor, upper-left dock.


func _exit_tree():
    # Clean-up of the plugin goes here.
    # Remove the dock.
    remove_control_from_docks(dock)
    # Erase the control from the memory.
    dock.free()

ドックは指定された位置に最初に表示されますが、ユーザーは自由に位置を変更し、結果のレイアウトを保存できることに注意してください。

結果の確認

It's now time to check the results of your work. Open the Project Settings and click on the Plugins tab. Your plugin should be the only one on the list.

../../../_images/making_plugins-project_settings.webp

You can see the plugin is not enabled. Click the Enable checkbox to activate the plugin. The dock should become visible before you even close the settings window. You should now have a custom dock:

../../../_images/making_plugins-custom_dock.webp

Registering autoloads/singletons in plugins

It is possible for editor plugins to automatically register autoloads when the plugin is enabled. This also includes unregistering the autoload when the plugin is disabled.

This makes setting up plugins faster for users, as they no longer have to manually add autoloads to their project settings if your editor plugin requires the use of an autoload.

Use the following code to register a singleton from an editor plugin:

@tool
extends EditorPlugin

# Replace this value with a PascalCase autoload name, as per the GDScript style guide.
const AUTOLOAD_NAME = "SomeAutoload"


func _enable_plugin():
    # The autoload can be a scene or script file.
    add_autoload_singleton(AUTOLOAD_NAME, "res://addons/my_addon/some_autoload.tscn")


func _disable_plugin():
    remove_autoload_singleton(AUTOLOAD_NAME)

Using sub-plugins

Often a plugin adds multiple things, for example a custom node and a panel. In those cases it might be easier to have a separate plugin script for each of those features. Sub-plugins can be used for this.

First create all plugins and sub plugins as normal plugins:

../../../_images/sub_plugin_creation.webp

Then move the sub plugins into the main plugin folder:

../../../_images/sub_plugin_moved.webp

Godot will hide sub-plugins from the plugin list, so that a user can't enable or disable them. Instead the main plugin script should enable and disable sub-plugins like this:

@tool
extends EditorPlugin

# The main plugin is located at res://addons/my_plugin/
const PLUGIN_NAME = "my_plugin"

func _enable_plugin():
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/node", true)
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/panel", true)

func _disable_plugin():
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/node", false)
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/panel", false)

今後の展開

基本的なプラグインの作成方法を学習したので、エディタをいくつかの方法で拡張できます。GDScriptを使用して、多くの機能をエディタに追加できます。これは、C++モジュールを詳しく掘り下げることなく、専用のエディタを作成するための強力な方法です。

自分でプラグインを作成して自分自身を助け、Asset Library で共有して、人々があなたの仕事から利益を得られるようにすることができます。