custom_modules - seraph526/godot-se GitHub Wiki

#C++自定义Modules

Modules

Godot允许通过模块的方式扩展引擎。可以创建新的模块,开启或关闭。这可以在不更改引擎核心代码的条件下在各个层级增加引擎的功能,可以分离使用,并且在不同的模块中复用。

模块是在编译文件的module或子文件夹中。默认条件下,存在两个模块,GDScript(它不是核心代码的一部分)和GridMap.许多新的模块可以按需求创建和组合。SCons编译系统会在相对用户透明的条件下编译它们。

What for?

虽然建议游戏的大部分代码都由脚本编写(因为这会节省大量时间),但也可以完美的用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,把模块分享给其他人。当编译时(前面有介绍),你的模块会包含在里面。

Using the Module

要使用你创建的模块很简单,任何脚本中你都可以:

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

Summing Up

看到了吧,使用C++开发Godot很简单。只要写你需要的东西,并记得: 使用OBJ_TYPE宏继承,以便Godot可以包含模块 使用_bind_methods绑定函数到脚本,允许它们以signals的callbacks方式执行。 但不只这些,取决于你做的东西,会带来一些惊喜。

如果继承自节点(Node)(或其他衍生的节点类型,如Sprite),你的新类会出现在编辑的"Add Node"对话框中。

如果继承自资源(Resource),它将会出现在资源列表中,所有暴露的属性在保存/读取时都可以被序列化。

按同样的逻辑,你可以扩展编辑器和引擎的任何区域。

⚠️ **GitHub.com Fallback** ⚠️