制作主屏幕插件

本教程涵盖的内容

Main screen plugins allow you to create new UIs in the central part of the editor, which appear next to the “2D”, “3D”, “Script”, and “AssetLib” buttons. Such editor plugins are referred as “Main screen plugins”.

本教程将带领你创建一个基本的主场景插件. 为了简单起见, 主场景插件将包含一个打印文本到控制台的单个按钮.

初始化插件

首先从Plugins菜单中创建一个新插件. 在本教程中, 我们将把它放在一个名为 main_screen 的文件夹中, 但你可以使用任何你喜欢的名字.

插件脚本会自带 _enter_tree()_exit_tree() 方法, 但对于主场景插件来说, 我们需要添加一些额外的方法. 增加五个额外的方法, 脚本就像这样:

GDScriptC#

  1. @tool
  2. extends EditorPlugin
  3. func _enter_tree():
  4. pass
  5. func _exit_tree():
  6. pass
  7. func _has_main_screen():
  8. return true
  9. func _make_visible(visible):
  10. pass
  11. func _get_plugin_name():
  12. return "Main Screen Plugin"
  13. func _get_plugin_icon():
  14. return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
  1. #if TOOLS
  2. using Godot;
  3. [Tool]
  4. public partial class MainScreenPlugin : EditorPlugin
  5. {
  6. public override void _EnterTree()
  7. {
  8. }
  9. public override void _ExitTree()
  10. {
  11. }
  12. public override bool _HasMainScreen()
  13. {
  14. return true;
  15. }
  16. public override void _MakeVisible(bool visible)
  17. {
  18. }
  19. public override string _GetPluginName()
  20. {
  21. return "Main Screen Plugin";
  22. }
  23. public override Texture2D _GetPluginIcon()
  24. {
  25. return EditorInterface.GetEditorTheme().GetIcon("Node", "EditorIcons");
  26. }
  27. }
  28. #endif

The important part in this script is the _has_main_screen() function, which is overloaded so it returns true. This function is automatically called by the editor on plugin activation, to tell it that this plugin adds a new center view to the editor. For now, we’ll leave this script as-is and we’ll come back to it later.

主画面场景

创建一个新的场景,其根节点由 Control 派生而来(在这个示例插件中,我们将使根节点为 CenterContainer)。选择这个根节点,在视口中,点击 布局 菜单,选择 整个矩形。你还需要在检查器中启用 Expand 垂直尺寸标志。面板现在使用主视口中的所有可用空间。

接下来, 让我们为我们的主屏幕插件示例添加一个按钮. 添加一个 Button 节点, 并将文本设置为 “Print Hello “或类似的内容. 给按钮添加一个脚本, 像这样:

GDScriptC#

  1. @tool
  2. extends Button
  3. func _on_print_hello_pressed():
  4. print("Hello from the main screen plugin!")
  1. using Godot;
  2. [Tool]
  3. public partial class PrintHello : Button
  4. {
  5. private void OnPrintHelloPressed()
  6. {
  7. GD.Print("Hello from the main screen plugin!");
  8. }
  9. }

然后将 “按下” 信号连接到自身. 如果你需要信号方面的帮助, 请参考 使用信号 一文.

我们完成了主屏幕面板. 将场景保存为 main_panel.tscn.

更新插件脚本

我们需要更新 main_screen_plugin.gd 脚本,让插件实例化我们的主面板场景,并将其放置在需要的位置。这是完整的插件脚本:

GDScriptC#

  1. @tool
  2. extends EditorPlugin
  3. const MainPanel = preload("res://addons/main_screen/main_panel.tscn")
  4. var main_panel_instance
  5. func _enter_tree():
  6. main_panel_instance = MainPanel.instantiate()
  7. # Add the main panel to the editor's main viewport.
  8. EditorInterface.get_editor_main_screen().add_child(main_panel_instance)
  9. # Hide the main panel. Very much required.
  10. _make_visible(false)
  11. func _exit_tree():
  12. if main_panel_instance:
  13. main_panel_instance.queue_free()
  14. func _has_main_screen():
  15. return true
  16. func _make_visible(visible):
  17. if main_panel_instance:
  18. main_panel_instance.visible = visible
  19. func _get_plugin_name():
  20. return "Main Screen Plugin"
  21. func _get_plugin_icon():
  22. # Must return some kind of Texture for the icon.
  23. return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons")
  1. #if TOOLS
  2. using Godot;
  3. [Tool]
  4. public partial class MainScreenPlugin : EditorPlugin
  5. {
  6. PackedScene MainPanel = ResourceLoader.Load<PackedScene>("res://addons/main_screen/main_panel.tscn");
  7. Control MainPanelInstance;
  8. public override void _EnterTree()
  9. {
  10. MainPanelInstance = (Control)MainPanel.Instantiate();
  11. // Add the main panel to the editor's main viewport.
  12. EditorInterface.GetEditorMainScreen().AddChild(MainPanelInstance);
  13. // Hide the main panel. Very much required.
  14. _MakeVisible(false);
  15. }
  16. public override void _ExitTree()
  17. {
  18. if (MainPanelInstance != null)
  19. {
  20. MainPanelInstance.QueueFree();
  21. }
  22. }
  23. public override bool _HasMainScreen()
  24. {
  25. return true;
  26. }
  27. public override void _MakeVisible(bool visible)
  28. {
  29. if (MainPanelInstance != null)
  30. {
  31. MainPanelInstance.Visible = visible;
  32. }
  33. }
  34. public override string _GetPluginName()
  35. {
  36. return "Main Screen Plugin";
  37. }
  38. public override Texture2D _GetPluginIcon()
  39. {
  40. // Must return some kind of Texture for the icon.
  41. return EditorInterface.GetEditorTheme().GetIcon("Node", "EditorIcons");
  42. }
  43. }
  44. #endif

增加了几行具体的内容. MainPanel 是一个常量, 持有对场景的引用, 我们将其实例化为 main_panel_instance.

The _enter_tree() function is called before _ready(). This is where we instance the main panel scene, and add them as children of specific parts of the editor. We use EditorInterface.get_editor_main_screen() to obtain the main editor screen and add our main panel instance as a child to it. We call the _make_visible(false) function to hide the main panel so it doesn’t compete for space when first activating the plugin.

当插件停用时, 调用 _exit_tree() 函数. 如果主屏幕仍然存在, 我们调用 queue_free() 来释放实例, 并将其从内存中移除.

The _make_visible() function is overridden to hide or show the main panel as needed. This function is automatically called by the editor when the user clicks on the main viewport buttons at the top of the editor.

The _get_plugin_name() and _get_plugin_icon() functions control the displayed name and icon for the plugin’s main viewport button.

另一个你可以添加的函数是 handles() 函数, 它允许你处理一个节点类型, 当选择该类型时自动聚焦主屏幕. 这类似于点击一个3D节点会自动切换到3D视口.

试试这个插件

在项目设置中激活插件. 你会观察到主视口上方的2D, 3D, 脚本旁边有一个新的按钮. 点击它将带你进入新的主屏幕插件, 中间的按钮将打印文本.

如果你想试试这个插件的完成版, 请在这里查看插件演示:https://github.com/godotengine/godot-demo-projects/tree/master/plugins

如果你想看一个更完整的例子, 了解主屏幕插件的能力, 请看这里的2.5D演示项目:https://github.com/godotengine/godot-demo-projects/tree/master/misc/2.5d