制作插件

下文仅针对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. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  2. iOS之绘制虚线

    /*   ** lineFrame:     虚线的 frame   ** length:        虚线中短线的宽度   ** spacing:       虚线中短线之间的间距   ** co ...

  3. Android 扫描条形码(Zxing插件)

    使用Android Studio 一.在build.gradle(Module:app)添加代码  下载,调用插件 1 apply plugin: 'com.android.application' ...

  4. [高性能MYSQL 读后随笔] 关于事务的隔离级别(一)

    一.锁的种类 MySQL中锁的种类很多,有常见的表锁和行锁,也有新加入的Metadata Lock等等,表锁是对一整张表加锁,虽然可分为读锁和写锁,但毕竟是锁住整张表,会导致并发能力下降,一般是做dd ...

  5. 用Taurus.MVC 做个企业站(下)

    前言: 上一篇完成了首页,这一篇就把剩下的几个功能给作了吧. 包括文章列表.文章详情和产品展示. 1:文章列表: 原来的ArticleList.aspx 1:现在的articlelist.html 除 ...

  6. fedora上部署ASP.NET——(卡带式电脑跑.NET WEB服务器)

    andrew,20130601,guilin 本文记录在树莓派(fedora)上部署ASP.NET MVC2 的过程. 本文共分为六部分,分别是前置条件,Apache的安装,Mysql的安装,安装mo ...

  7. centos7+mono4.2.3.4+jexus5.8.1跨平台起飞

    很早之前就开始关注.net跨平台,最近正好测试了下用EF6连接mysql,于是就想直接把网站扔进Linux.查了很多资料,鼓捣了两个晚上,终于成功. 这里我使用的是budgetvm的1G openvz ...

  8. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  9. Cowboy 开源 WebSocket 网络库

    Cowboy.WebSockets 是一个托管在 GitHub 上的基于 .NET/C# 实现的开源 WebSocket 网络库,其完整的实现了 RFC 6455 (The WebSocket Pro ...

  10. 浅谈跨域以及WebService对跨域的支持

    跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问.也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源. 在 ...