制作插件

下文仅针对2.1版本。

关于插件

插件是为编辑器扩展出更多有用工具的重要方式。它可以完全用GDScript和标准场景开发,甚至都不需重新加载编辑器就可生效。不像模块,你无需创建C++代码、也无需重新编译整个引擎。这使得插件可能不够强大,但仍能用之完成很多事情。注:插件与你已经制作的任何场景没有不同,除了它是通过脚本添加功能。

该手册将会通过两个简单插件的创建来让你理解其工作原理并自行开发。首先,在项目中添加一个自定义节点到任意场景,然后就会有一个自定义Dock添加到编辑中。

创建插件

开始前,先新建一个空项目,用于开发和 测试插件。

项目目录下,有存放插件的标准目录addons/plugin_name,所以,在addons`目录中创建一个叫my_custom_node``的目录,目录结构类似于:

创建plugin.cfg文件,Godot还不能打开这种文件所以必须在外部编辑器中编辑其内容:

  1. [plugin]
  2. name="My Custom Node"
  3. description="A custom node made to extend the Godot Engine."
  4. author="Your Name Here"
  5. version="1.0"
  6. script="custom_node.gd"

这是有关你这个插件的元数据,需要设置名称和描述以便用户理解其作用。当插件激活时,会加载你指定的主脚本文件。指定版本号后,用户可以去判定是否是一个过期版本(关于语义化版本规范可以参看:http://semver.org/lang/zh-CN/)。

脚本文件

打开脚本编辑器(F3)并创建一个在 my_custom_node目录下的名为custom_node.gd的GDScript文件。该脚本有两点特殊要求:它必须是 tool脚本;必须继承自EditorPlugin类。

有项很重要的工作是初始化并清空资源。一种好的实践方式是用虚拟函数_enter_tree() <class_Node__enter_tree>来初始化插件以及用_exit_tree() <class_Node__exit_tree>来清空它。你可以删除默认的GDScript模板内容并用以下代码结构替换:


  1. tool
  2. extends EditorPlugin
  3. func _enter_tree():
  4. # Initialization of the plugin goes here
  5. pass
  6. func _exit_tree():
  7. # Clean-up of the plugin goes here
  8. pass

这段模板代码在开发新插件时一般都可以用到。

自定义节点

有时你想让多个节点拥有某种特定的行为,可能通过重用自定义场景或控件可实现这种需求;场景实例化在很多情况是有用的,但有时会显得累赘,尤其被用于多个项目中时。这时好的解决方案是制作一个插件,用于添加带有自定义行为的节点。

要新建一种节点类型,通过class_EditorPlugin类的add_custom_type() <class_EditorPlugin_add_custom_type>函数。该函数能给编辑器添加新的类型,可以是节点或资源。不过在创建类型之前,你需要一个脚本用于承载其逻辑。这种脚本不需要用tool关键词来修饰,仅仅是让用户可以在编辑器中看到它。

我们来创建一个简单的按钮,效果是:当其被点击时,打印一条消息。我们需要一段简单脚本,继承自Button类,也可以继承自BaseButton类:

  1. tool
  2. extends Button
  3. func _enter_tree():
  4. connect("pressed", self, "clicked")
  5. func clicked():
  6. print("You clicked me!")

将代码文件命名为 button.gd保存到插件目录。还需要一个16x16的小图标用来显示在场景树中。如果没有,可以暂时用场景中的默认图标。

我们来将其添加为自定义类型以便在Create New Node对话框中显示,修改custom_node.gd脚本代码:

  1. tool
  2. extends EditorPlugin
  3. func _enter_tree():
  4. # Initialization of the plugin goes here
  5. # Add the new type with a name, a parent type, a script and an icon
  6. add_custom_type("MyButton", "Button", preload("button.gd"), preload("icon.png"))
  7. func _exit_tree():
  8. # Clean-up of the plugin goes here
  9. # Always remember to remove it from the engine when deactivated
  10. remove_custom_type("MyButton")

做完这个操作,在项目设置的插件列表中,这个插件应该就出现了,激活它,并试着添加一个新的节点来看看效果:

添加了节点后,你会看到脚本已经被附着到该节点上。设置按钮的文本,保存并运行场景。点击按钮,应该就能看到控制台中输出的文本:

自定义Dock

有时你需要通过扩展编辑器来添加已经存在的工具,一种简单的方式是通过插件添加一个新的Dock。Dock是基于控件的场景,所以没有新的知识点啦。

创建插件的方式与自定义节点的方式相似,所以在 addons/my_custom_dock 目录下新建一个plugin.cfg文件。添加内容:

  1. [plugin]
  2. name="My Custom Dock"
  3. description="A custom dock made so I can learn how to make plugins."
  4. author="Your Name Here"
  5. version="1.0"
  6. script="custom_dock.gd"

Dock的内容其实完全就是标准的Godot场景。

对于编辑器Dock来说,场景的根节点强制为Control 类或其子类。根节点的名称也将是出现在Dock选项卡上的名称,所以要剪短精炼,别忘了给按钮添加一段文本:

将场景保存为 my_dock.tscn

选取刚刚创建的场景,以Dock的形式添加到编辑器中 - 依赖EditorPlugin类的add_control_to_dock()的函数:

代码很直观,选定好Dock的位置。当插件失活时,要记得移除Dock:

  1. tool
  2. extends EditorPlugin
  3. var dock # A class member to hold the dock during the plugin lifecycle
  4. func _enter_tree():
  5. # Initialization of the plugin goes here
  6. # First load the dock scene and instance it:
  7. dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()
  8. # Add the loaded scene to the docks:
  9. add_control_to_dock( DOCK_SLOT_LEFT_UL, dock)
  10. # Note that LEFT_UL means the left of the editor, upper-left dock
  11. func _exit_tree():
  12. # Clean-up of the plugin goes here
  13. # Remove the scene from the docks:
  14. remove_control_from_docks( dock ) # Remove the dock
  15. dock.free() # Erase the control from the memory

用户可以自由移动Dock的未知,并保存dock的布局位置。

检验结果

打开“Project Settings”,点击“Plugin”选项卡,你的插件应该出现在列表中,如果并未出现,点击右上角“Update”按钮:

在“Status”列中,显示该插件是未激活的,只要点击状态并选择“激活”即可,而Dock也会即时显示。

更深入的内容

既然你已学习了如何制作简单的插件,你就可以用很多很好的方式来扩展编辑器。通过GDScript可以给编辑器快速添加很多功能函数,从而创建出所需的特定编辑器,而无需研究C++模块。

你可以制作插件来助力自己的开发工作,也可以将这些插件分享到Godot的Asset Library以便更多的人受益。

[译]Godot系列教程五 - 制作Godot编辑器插件的更多相关文章

  1. PyQt5系列教程(五)制作fastboot烧写器

    软硬件环境 Windows 7 Python 3.4.2 PyQt 5.5.1 PyCharm 5.0.2 前言 fastboot是针对Android设备的一种刷机方式,它比recovery更底层,刷 ...

  2. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  3. NGUI系列教程五(角色信息跟随)

    在一些网络游戏中,我们常常可以看到角色的上方显示着角色的名称,等级,血量等信息.它们可以跟随角色移动,并且可以显示和隐藏.今天我们就来学习一下这些功能的实现方法.1. 新建unity工 程,导入NGU ...

  4. CRL快速开发框架系列教程五(使用缓存)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  5. C#微信公众号开发系列教程五(接收事件推送与消息排重)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  6. 黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block 企业库数据库访问模块通过抽象工厂模式,允许用户 ...

  7. Unity3D脚本中文系列教程(五)

    http://dong2008hong.blog.163.com/blog/static/4696882720140302848544/?suggestedreading&wumii Unit ...

  8. Influx Sql系列教程五:insert 添加数据

    接下来开始进入influxdb的curd篇,首先我们看一下如何添加数据,也就是insert的使用姿势 在进入本篇之前,对于不了解什么是retention policy, tag, field的同学,有 ...

  9. [译]Godot系列教程三 - 场景实例化(续)

    场景实例化(续) 要点 场景实例化带来很多便利的用法,总体来说有: 将场景细分,更便于管理 相对于某些引擎中的Prefab组件更灵活,并且在许多方面更强大 是一种设计更复杂的游戏流程甚至UI的方式 这 ...

随机推荐

  1. 从display:run-in;中学习新技能

    有时我们想在一行内显示一个标题,以及一段内容,虽然看起来比较简单,但是为了语义化用dl比较合适,但是它默认是block元素,改成inline?那么有多段呢?不就都跑上来了?用float?那问题也挺多. ...

  2. Visual Studio 2013 添加一般应用程序(.ashx)文件到SharePoint项目

    默认,在用vs2013开发SharePoint项目时,vs没有提供一般应用程序(.ashx)的项目模板,本文解决此问题. 以管理员身份启动vs2013,创建一个"SharePoint 201 ...

  3. atitit.attilax的软件 架构 理念.docx

    atitit.attilax的软件 架构 理念.docx 1. 预先规划.1 2. 全体系化1 3. 跨平台2 4. 跨语言2 5. Dsl化2 5.1. 界面ui h5化2 6. 跨架构化2 7. ...

  4. Linux实战教学笔记07:Linux系统目录结构介绍

    第七节 Linux系统目录结构介绍 标签(空格分隔):Linux实战教学笔记 第1章 前言 windows目录结构 C:\windows D:\Program Files E:\你懂的\精品 F:\你 ...

  5. 解决WINDOWS防火墙开启后Ping不通

    WINDOWS系统由于安全考虑,当开启防火墙时,默认不允许外主机对其进行ping功能,即别的电脑ping不通本机.别的主机ping不通本机是因为本机的防火墙关闭了ICMP回显功能,只要把这回显功能打开 ...

  6. C#非常重要基础之多态

    前几天看了一位同志的博客,写的是关于他自己去支付宝面试的经历.过程大体是这样的:问答的时候,前面部分,作者都应答如流,说起自己经验如何之丰富,最后面试官问了作者一个问题:请简述多态的概念和作用.结果这 ...

  7. ABP(现代ASP.NET样板开发框架)系列之10、ABP领域层——实体

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之10.ABP领域层——实体 ABP是“ASP.NET Boilerplate Project (ASP.NET样板 ...

  8. ABP源码分析二十五:EventBus

    IEventData/EventData: 封装了EventData信息,触发event的源对象和时间 IEventBus/EventBus: 定义和实现了了一系列注册,注销和触发事件处理函数的方法. ...

  9. ABP源码分析四十三:ZERO的本地化

    ABP Zero模块扩展了ABP基础框架中的本地化功能,实现了通过数据库管理本地化的功能.其通过数据库保存本地化语言及其资源. ApplicationLanguage:代表本地化语言的实体类.一种语言 ...

  10. T-SQL:毕业生出门需知系列(九)

    <SQL 必知必会>读书笔记 -- 第9课 汇总数据 9.1 聚集函数:对某些行运行的函数,计算并返回一个值 案例: -- 确定表中函数 -- 获得表中某些行的和 -- 找出表列的最大值. ...