制作插件

下文仅针对2.1版本。

关于插件

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

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

创建插件

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

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

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

[plugin]

name="My Custom Node"
description="A custom node made to extend the Godot Engine."
author="Your Name Here"
version="1.0"
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模板内容并用以下代码结构替换:


tool
extends EditorPlugin func _enter_tree():
# Initialization of the plugin goes here
pass func _exit_tree():
# Clean-up of the plugin goes here
pass

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

自定义节点

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

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

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

tool
extends Button func _enter_tree():
connect("pressed", self, "clicked") func clicked():
print("You clicked me!")

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

我们来将其添加为自定义类型以便在Create New 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("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")

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

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

自定义Dock

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

创建插件的方式与自定义节点的方式相似,所以在 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"

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

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

将场景保存为 my_dock.tscn

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

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

tool
extends EditorPlugin var dock # A class member to hold the dock during the plugin lifecycle func _enter_tree():
# Initialization of the plugin goes here
# First 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 scene from the docks:
remove_control_from_docks( dock ) # Remove the dock
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. 微信小程序教程汇总

    目前市面上在内测期间出来的一些实战类教程还是很不错的,主要还是去快速学习小程序开发的整体流程,一个组件一个组件的讲的很可能微信小程序一升级,这个组件就变了,事实本就如此,谁让现在是内测呢.我们不怕,下 ...

  2. CSS3自定义滚动条样式 -webkit-scrollbar(转)

    有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...

  3. ES6之变量常量字符串数值

    ECMAScript 6 是 JavaScript 语言的最新一代标准,当前标准已于 2015 年 6 月正式发布,故又称 ECMAScript 2015. ES6对数据类型进行了一些扩展 在js中使 ...

  4. 【centos7常用技巧】RPM打包

    一.RPM打包的目的 1.当目标机中不存在编译环境时,可以先在本地环境中编译打包,然后直接在目标机中用rpm -ivh *.rpm安装即可. 2.当需要在目标机中安装多个软件或者增加多个文件时,可以将 ...

  5. 转:MSSQL还原单mdf文件报1813错误

    原文地址:http://www.cnblogs.com/clownkings/p/4950865.html 解决办法: 1.首先要备份好mdf文件,如果他没了经理非吃了你不可.都不吐骨头的. 2.在数 ...

  6. MySQL 数据库双向同步复制

    MySQL 复制问题的最后一篇,关于双向同步复制架构设计的一些设计要点与制约. 问题和制约 数据库的双主双写并双向同步场景,主要考虑数据完整性.一致性和避免冲突.对于同一个库,同一张表,同一个记录中的 ...

  7. 微信小程序之用户数据解密(七)

    [未经作者本人同意,请勿以任何形式转载] 经常看到有点的小伙伴在群里问小程序用户数据解密流程,所以打算写一篇关于小程序用户敏感数据解密教程: 加密过程微信服务器完成,解密过程在小程序和自身服务器完成, ...

  8. 学习笔记:7z在delphi的应用

    最近做个发邮件的功能,需要将日志文件通过邮件发送回来用于分析,但是日志文件可能会超级大,测算下来一天可能会有800M的大小.所以压缩是不可避免了,delphi中的默认压缩算法整了半天不太好使,就看了看 ...

  9. ASP.NET MVC Model元数据(五)

    ASP.NET MVC Model元数据(五) 前言 在上一篇中我们描述了应用于Model上面的各种用于显示控制的特性类,在本篇中将详细的介绍这些特性类的应用,虽然它们跟Model元数据的直接关系并不 ...

  10. ABP框架 - 应用服务

    文档目录 本节内容: IApplicationService 接口 ApplicationService 类 CrudAppService 和 AsyncCrudAppService 类 简单的CRU ...