custom_modules - seraph526/godot-se GitHub Wiki
#C++自定义Modules
Godot允许通过模块的方式扩展引擎。可以创建新的模块,开启或关闭。这可以在不更改引擎核心代码的条件下在各个层级增加引擎的功能,可以分离使用,并且在不同的模块中复用。
模块是在编译文件的module或子文件夹中。默认条件下,存在两个模块,GDScript(它不是核心代码的一部分)和GridMap.许多新的模块可以按需求创建和组合。SCons编译系统会在相对用户透明的条件下编译它们。
虽然建议游戏的大部分代码都由脚本编写(因为这会节省大量时间),但也可以完美的用C++代替。增加C++模块在下述场景时会非常有用:
绑定一个外部的库到Godot(如Bullet, Physx, FMOD等等). 优化游戏的临界部分。 添加新的功能到游戏引擎或编辑器。 移植一个已经存在的游戏。 用C++写一个全新的游戏,因为没有C++你就没办法活下去。 创建一个新的模块.
要创建一个新的模块,第一步是在modules文件夹中创建一个子文件夹。如果你要保持模块的独立性,你可以在modules中创建版本控制。
示例中的模块叫做"sumator"
c:\godot> cd modules
c:\godot> mkdir sumator
c:\godot> cd sumator
c:\godot\sumator>
在此文件夹风我们创建一个简单的sumator类:
/* sumator.h */
#ifndef SUMATOR_H
#define SUMATOR_H
#include "reference.h"
class Sumator : public Reference {
OBJ_TYPE(Sumator,Reference);
int count;
protected:
static void _bind_methods();
public:
void add(int value);
void reset();
int get_total() const;
Sumator();
};
#endif
然后是cpp文件.
/* sumator.cpp */
#include "sumator.h"
void Sumator::add(int value) {
count+=value;
}
void Sumator::reset() {
count=0;
}
int Sumator::get_total() const {
return count;
}
void Sumator::_bind_methods() const {
ObjectTypeDB::bind_method("add",&Sumator::add);
ObjectTypeDB::bind_method("reset",&Sumator::reset);
ObjectTypeDB::bind_method("get_total",&Sumator::get_total);
}
Sumator::Sumator() {
count=0;
}
然后,新类要注册一些东西。还要再创建两个文件:
register_types.h register_types.cpp
内容如下:
/* register_types.h */
void register_sumator_types();
void unregister_sumator_types();
/* yes, the word in the middle must be the same as the module folder name */
/* register_types.cpp */
#include "register_types.h"
#include "object_type_db.h"
void register_sumator_types() {
ObjectTypeDB::register_type<Sumator>();
}
void unregister_sumator_types() {
//nothing to do here
}
然后创建SCsub文件,以便系统可以编译这个模块:
# SCsub
Import('env')
env.add_source_files(env.modules_sources,"*.cpp") # just add all cpp files to the build
最后是模块的配置文件,它是一个简单的python脚本,名字固定为"config.py"
# config.py
def can_build(platform):
return True
def configure(env):
pass
这部分是说此模块是否为特别的平台使用(这里,true是说所有的平台都编译).
第二个函数允许为模块自定义编译进程,如添加特别的编译flags,选项等。(这也可以在SCSub里完成,但configure(env)在前面的阶段调用),如果不确定,可以忽略。
好了,希望它不是很复杂!你的module看起来是这个样子:
modules/config.py
modules/sumator.h
modules/sumator.cpp
modules/register_types.h
modules/register_types.cpp
modules/SCsub
你可以打包成zip,把模块分享给其他人。当编译时(前面有介绍),你的模块会包含在里面。
要使用你创建的模块很简单,任何脚本中你都可以:
var s = Sumator.new()
s.add(10)
s.add(20)
s.add(30)
print( s.get_total() )
s.reset()
And the output will be:
60
看到了吧,使用C++开发Godot很简单。只要写你需要的东西,并记得: 使用OBJ_TYPE宏继承,以便Godot可以包含模块 使用_bind_methods绑定函数到脚本,允许它们以signals的callbacks方式执行。 但不只这些,取决于你做的东西,会带来一些惊喜。
如果继承自节点(Node)(或其他衍生的节点类型,如Sprite),你的新类会出现在编辑的"Add Node"对话框中。
如果继承自资源(Resource),它将会出现在资源列表中,所有暴露的属性在保存/读取时都可以被序列化。
按同样的逻辑,你可以扩展编辑器和引擎的任何区域。