制作插件¶
关于插件¶
插件是用有用的工具扩展编辑器的一个很好的方法。它完全可以用gdscript和标准场景制作,甚至不需要重新加载编辑器。与模块不同,您不需要创建C++代码,也不需要重新编译引擎。虽然这会降低插件的功能,但您仍然可以用它们做很多事情。请注意,插件类似于您已经创建的任何场景,只是它是使用脚本添加功能创建的。
本教程将指导您创建两个简单的插件,以便您了解它们是如何工作的,并能够开发自己的插件。第一个将是一个自定义节点,您可以将其添加到项目中的任何场景,另一个将是一个添加到编辑器中的自定义停靠。
创建插件¶
在开始之前,在任何需要的地方创建一个新的空项目。这将作为开发和测试插件的基础。
您需要做的第一件事是创建一个编辑器可以理解的新插件。您需要两个文件: plugin.cfg
用于配置和具有此功能的自定义gdscript。
插件有一个标准的路径 addons/plugin_name
在项目文件夹中。对于本例,创建一个文件夹 my_custom_node
里面 addons
. 您应该以这样的目录结构结束:
现在,打开脚本编辑器,单击 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图标。
现在,我们需要将其添加为自定义类型,以便在 创建新节点 对话。为此,改变 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 .
然后通过添加新节点进行尝试:
添加节点时,可以看到它已经附加了您创建的脚本。设置按钮的文本,保存并运行场景。单击按钮时,可以在控制台中看到一些文本:
定制码头¶
有时,您需要扩展编辑器并添加始终可用的工具。一个简单的方法是用一个插件添加一个新的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选项卡上显示的名称,因此请确保给它一个简短的描述性名称。另外,不要忘记在按钮上添加一些文本。
将此场景另存为 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
请注意,虽然停靠最初将显示在其指定位置,但用户可以自由更改其位置并保存生成的布局。
检查结果¶
现在是时候检查一下你的工作成果了。打开 项目设置 然后点击 插件 标签。您的插件应该是列表中唯一的一个。如果没有显示,请单击 更新 按钮位于右上角。
您可以看到插件在 状态 列;单击要选择的状态 主动的 . 在关闭“设置”窗口之前,应该可以看到停靠。您现在应该有一个自定义停靠:
超越¶
既然您已经学习了如何制作基本插件,那么您可以通过多种方式扩展编辑器。许多功能可以用GDScript添加到编辑器中,这是一个强大的方法来创建专门的编辑器而不必深入研究C++模块。
您可以制作自己的插件来帮助自己并在 Asset Library 这样人们就可以从你的工作中获益。