制作插件

关于插件

插件是用有用的工具扩展编辑器的一个很好的方法。它完全可以用gdscript和标准场景制作,甚至不需要重新加载编辑器。与模块不同,您不需要创建C++代码,也不需要重新编译引擎。虽然这会降低插件的功能,但您仍然可以用它们做很多事情。请注意,插件类似于您已经创建的任何场景,只是它是使用脚本添加功能创建的。

本教程将指导您创建两个简单的插件,以便您了解它们是如何工作的,并能够开发自己的插件。第一个将是一个自定义节点,您可以将其添加到项目中的任何场景,另一个将是一个添加到编辑器中的自定义停靠。

创建插件

在开始之前,在任何需要的地方创建一个新的空项目。这将作为开发和测试插件的基础。

您需要做的第一件事是创建一个编辑器可以理解的新插件。您需要两个文件: plugin.cfg 用于配置和具有此功能的自定义gdscript。

插件有一个标准的路径 addons/plugin_name 在项目文件夹中。对于本例,创建一个文件夹 my_custom_node 里面 addons . 您应该以这样的目录结构结束:

../../../_images/making_plugins-my_custom_mode_folder.png

现在,打开脚本编辑器,单击 File 菜单选择 新建文本文件 ,然后导航到插件文件夹并命名该文件 plugin.cfg . 将以下结构添加到 plugin.cfg

[plugin]

name="My Custom Node"
description="A custom node made to extend the Godot Engine."
author="Your Name Here"
version="1.0.0"
script="custom_node.gd"
[plugin]

name="My Custom Node"
description="A custom node made to extend the Godot Engine."
author="Your Name Here"
version="1.0.0"
script="CustomNode.cs"

这是一个包含插件元数据的简单ini文件。你需要设置名称和描述,这样人们才能理解它的作用。别忘了加上你自己的名字,这样你就可以得到正确的学分。添加一个版本号,这样人们可以看到他们是否有一个过时的版本;如果您不确定如何得出版本号,请签出 Semantic Versioning . 最后,将主脚本文件设置为在插件处于活动状态时加载。

脚本文件

打开脚本编辑器(f3)并创建一个名为 custom_node.gd 里面 my_custom_node 文件夹。这个脚本是特殊的,它有两个要求:必须是 tool 脚本,它必须继承自 EditorPlugin .

处理资源的初始化和清理非常重要。一个好的实践是使用虚函数 _enter_tree() 初始化插件和 _exit_tree() 把它清理干净。您可以从文件中删除默认的gdscript模板,并将其替换为以下结构:

tool
extends EditorPlugin

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

func _exit_tree():
    # Clean-up of the plugin goes here
    pass
#if TOOLS
using Godot;
using System;

[Tool]
public class CustomNode : EditorPlugin
{
    public override void _EnterTree()
    {
        // Initialization of the plugin goes here
    }

    public override void _ExitTree()
    {
        // Initialization of the plugin goes here
    }
}
#endif

这是创建新插件时要使用的一个好模板。

自定义节点

有时,您希望在许多节点中有特定的行为,例如可以重用的自定义场景或控件。实例化在很多情况下都很有用,但有时它会很麻烦,特别是在许多项目中使用它时。一个很好的解决方案是制作一个插件,添加一个具有自定义行为的节点。

要创建新的节点类型,可以使用函数 add_custom_type()EditorPlugin 类。此函数可以向编辑器添加新类型(节点或资源)。但是,在创建类型之前,需要一个脚本来充当该类型的逻辑。虽然该脚本不必使用 tool 关键字,可以添加它以便脚本在编辑器中运行。

对于本教程,我们将创建一个简单的按钮,在单击时打印一条消息。为此,我们需要一个简单的脚本, 纽扣 . 它还可以扩展 BaseButton 如果您愿意:

tool
extends Button

func _enter_tree():
    connect("pressed", self, "clicked")

func clicked():
    print("You clicked me!")
using Godot;
using System;

[Tool]
public class MyButton : Button
{
    public override void _EnterTree()
    {
        Connect("pressed", this, "clicked");
    }

    public void clicked()
    {
        GD.Print("You clicked me!");
    }
}

这就是我们的基本按钮。您可以将此另存为 my_button.gd 在插件文件夹中。您还需要一个16×16的图标来显示在场景树中。如果没有,可以从引擎中获取默认值并将其保存到 addons/my_custom_node 文件夹为 icon.png 或使用默认的godot徽标 (preload("res://icon.png") )如果需要,也可以使用SVG图标。

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

现在,我们需要将其添加为自定义类型,以便在 创建新节点 对话。为此,改变 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")
#if TOOLS
using Godot;
using System;

[Tool]
public class CustomNode : EditorPlugin
{
    public override void _EnterTree()
    {
        // Initialization of the plugin goes here
        // Add the new type with a name, a parent type, a script and an icon
        var script = GD.Load<Script>("addons/MyButton.cs");
        var texture = GD.Load<Texture>("icon.png");
        AddCustomType("MyButton", "Button", script, texture);
    }

    public override void _ExitTree()
    {
        // Clean-up of the plugin goes here
        // Always remember to remove it from the engine when deactivated
        RemoveCustomType("MyButton");
    }
}
#endif

完成后,插件应该已经在插件列表中 项目设置 ,激活它,如中所述 Checking the results .

然后通过添加新节点进行尝试:

../../../_images/making_plugins-custom_node_create.png

添加节点时,可以看到它已经附加了您创建的脚本。设置按钮的文本,保存并运行场景。单击按钮时,可以在控制台中看到一些文本:

../../../_images/making_plugins-custom_node_console.png

定制码头

有时,您需要扩展编辑器并添加始终可用的工具。一个简单的方法是用一个插件添加一个新的Dock。Dock只是基于控件的场景,因此它们的创建方式与通常的GUI场景类似。

创建自定义停靠就像创建自定义节点一样完成。新建 plugin.cfg 文件中 addons/my_custom_dock 文件夹,然后向其中添加以下内容:

[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"
[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="CustomDock.cs"

然后创建脚本 custom_dock.gd 在同一文件夹中。把它装满 template we've seen before 为了一个好的开始。

因为我们试图添加一个新的自定义停靠,所以我们需要创建停靠的内容。这只是一个标准的Godot场景:只需在编辑器中创建一个新场景,然后编辑它。

对于编辑器停靠,根节点 must 是一个 Control 或者它的一个子类。对于本教程,可以创建单个按钮。根节点的名称也将是Dock选项卡上显示的名称,因此请确保给它一个简短的描述性名称。另外,不要忘记在按钮上添加一些文本。

../../../_images/making_plugins-my_custom_dock_scene.png

将此场景另存为 my_dock.tscn . 现在,我们需要抓取我们创建的场景,然后在编辑器中将其添加为停靠。为此,您可以依赖函数 add_control_to_dock()EditorPlugin 班级。

您需要选择一个停靠位置并定义要添加的控件(这是您刚刚创建的场景)。别忘了 移除码头 当插件被停用时。脚本可能如下所示:

tool
extends EditorPlugin

# A class member to hold the dock during the plugin lifecycle
var dock

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

    # 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()
#if TOOLS
using Godot;
using System;

[Tool]
public class CustomDock : EditorPlugin
{
    Control dock;

    public override void _EnterTree()
    {
        dock = (Control)GD.Load<PackedScene>("addons/my_custom_dock/my_dock.tscn").Instance();
        AddControlToDock(DockSlot.LeftUl, dock);
    }

    public override void _ExitTree()
    {
        // Clean-up of the plugin goes here
        // Remove the dock
        RemoveControlFromDocks(dock);
        // Erase the control from the memory
        dock.Free();
    }
}
#endif

请注意,虽然停靠最初将显示在其指定位置,但用户可以自由更改其位置并保存生成的布局。

检查结果

现在是时候检查一下你的工作成果了。打开 项目设置 然后点击 插件 标签。您的插件应该是列表中唯一的一个。如果没有显示,请单击 更新 按钮位于右上角。

../../../_images/making_plugins-project_settings.png

您可以看到插件在 状态 列;单击要选择的状态 主动的 . 在关闭“设置”窗口之前,应该可以看到停靠。您现在应该有一个自定义停靠:

../../../_images/making_plugins-custom_dock.png

超越

既然您已经学习了如何制作基本插件,那么您可以通过多种方式扩展编辑器。许多功能可以用GDScript添加到编辑器中,这是一个强大的方法来创建专门的编辑器而不必深入研究C++模块。

您可以制作自己的插件来帮助自己并在 Asset Library 这样人们就可以从你的工作中获益。