godot 4.4.x 版本配置 GDExtension 环境

421 阅读3分钟

GDExtension的Visual Studio环境配置

个人在godot开发时,配置GDExtension开发环境记录。

个人所使用的环境

  • Windows 11
  • Python 3.8.x
  • Visual Studio 2022
  • godot 4.4
  • SCons 4.9.1
  • godot-cpp

环境配置

完成Python安装执行

pip install scons 

克隆或下载godot版本相符的godot-cpp

创建目录

把刚才下载的仓库改名godot-cpp并和下方目录结构保持一致。

project
    source       // godot游戏项目源码目录
    godot-cpp    // godot-cpp目录
    gamelib-vs   // vs 项目目录
    SConstruct   // SConstruct 编译文件

extension_api

在仓库下的gdextension目录已经带了一份extension_api.json。 当你发现仓库与现有中的配置不一致时,你需要自己手动生成一份。

    godot --dump-extension-api    // godot是你的引擎

并把生成的extension_api.json 复制到godot-cpp根目录下并在当前目录下执行

    # platform 是你的平台 我默认就填写了 windows
    scons platform=<platform> custom_api_file=extension_api.json

等待命令执行完毕.

VS项目创建

打开VS 创建一个空的项目,配置类型设置为dll。 1.png

设置VC++目录的包目录
..\godot-cpp\gdextension
..\godot-cpp\include
..\godot-cpp\gen\include

2.png

实现插件

gdexample.h
#pragma once

#ifndef GDEXAMPLE_H
#define GDEXAMPLE_H

#include <godot_cpp/classes/sprite2d.hpp>

namespace godot {

	class GDExample : public Sprite2D {
		GDCLASS(GDExample, Sprite2D)

	private:
		double time_passed;

	protected:
		static void _bind_methods();

	public:
		GDExample();
		~GDExample();

		void _process(double delta) override;
	};
}

#endif
gdexample.cpp
#include "gdexample.h"
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

void GDExample::_bind_methods() {
}

GDExample::GDExample() {
	// Initialize any variables here.
	time_passed = 0.0;
}

GDExample::~GDExample() {
	// Add your cleanup here.
}

void GDExample::_process(double delta) {
	time_passed += delta;

	Vector2 new_position = Vector2(10.0 + (10.0 * sin(time_passed * 2.0)), 10.0 + (10.0 * cos(time_passed * 1.5)));

	set_position(new_position);
}

编写注册函数

register_types.h
#pragma once

#ifndef GAME_LIB_REGISTER_TYPES_H
#define GAME_LIB_REGISTER_TYPES_H

#include <godot_cpp/core/class_db.hpp>

using namespace godot;

void initialize_example_module(ModuleInitializationLevel p_level);
void uninitialize_example_module(ModuleInitializationLevel p_level);

#endif // GAME_LIB_REGISTER_TYPES_H
register_types.cpp
#include "register_types.h"

#include "gdexample.h"

#include <gdextension_interface.h>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>

using namespace godot;

void initialize_example_module(ModuleInitializationLevel p_level) {
	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
		return;
	}

	GDREGISTER_RUNTIME_CLASS(GDExample);
}

void uninitialize_example_module(ModuleInitializationLevel p_level) {
	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
		return;
	}
}

extern "C" {
	// Initialization.
	GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization* r_initialization) {
		godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);

		init_obj.register_initializer(initialize_example_module);
		init_obj.register_terminator(uninitialize_example_module);
		init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);

		return init_obj.init();
	}
}

编译插件

编译插件需要手工编写SConstruct​文件,这并不容易,官方提供一个根据本例硬编码的文件。如下所示:

#!/usr/bin/env python
import os
import sys

env = SConscript("godot-cpp/SConstruct")

# For reference:
# - CCFLAGS are compilation flags shared between C and C++
# - CFLAGS are for C-specific compilation flags
# - CXXFLAGS are for C++-specific compilation flags
# - CPPFLAGS are for pre-processor flags
# - CPPDEFINES are for pre-processor defines
# - LINKFLAGS are for linking flags

# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=["game-lib-vs/"])
sources = Glob("game-lib-vs/*.cpp")

if env["platform"] == "macos":
    library = env.SharedLibrary(
        "source/bin/libgame.{}.{}.framework/libgdexample.{}.{}".format(
            env["platform"], env["target"], env["platform"], env["target"]
        ),
        source=sources,
    )
elif env["platform"] == "ios":
    if env["ios_simulator"]:
        library = env.StaticLibrary(
            "source/bin/libgame.{}.{}.simulator.a".format(env["platform"], env["target"]),
            source=sources,
        )
    else:
        library = env.StaticLibrary(
            "source/bin/libgame.{}.{}.a".format(env["platform"], env["target"]),
            source=sources,
        )
else:
    library = env.SharedLibrary(
        "source/bin/libgame.{}.{}".format(env["suffix"], env["SHLIBSUFFIX"]),
        source=sources,
    )

Default(library)

将该文件放入项目根目录,即Project/​,与godot-cpp​,source​,gamelib-vs​同级,然后开始执行编译操作,执行如下命令

    scons platform=<platform>

编译完成后你现在应该能够在source/bin​ 中找到该模块.

在这里,我们将 godot-cpp 和我们的 gdexample 库编译为调试版本。对于优化的构建,应使用target=template_release​开关进行编译。

使用GDExtension模块

[configuration]

entry_symbol = "example_library_init"
compatibility_minimum = "4.1"

[libraries]

macos.debug = "res://bin/libgame.macos.template_debug.framework"
macos.release = "res://bin/libgame.macos.template_release.framework"
windows.debug.x86_32 = "res://bin/libgame.windows.template_debug.x86_32.dll"
windows.release.x86_32 = "res://bin/libgame.windows.template_release.x86_32.dll"
windows.debug.x86_64 = "res://bin/libgame.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "res://bin/libgame.windows.template_release.x86_64.dll"
windows.debug.arm64 = "res://bin/libgame.windows.template_debug.arm64.dll"
windows.release.arm64 = "res://bin/libgame.windows.template_release.arm64.dll"
linux.debug.x86_32 = "res://bin/libgame.linux.template_debug.x86_32.so"
linux.release.x86_32 = "res://bin/libgame.linux.template_release.x86_32.so"
linux.debug.x86_64 = "res://bin/libgame.linux.template_debug.x86_64.so"
linux.release.x86_64 = "res://bin/libgame.linux.template_release.x86_64.so"
linux.debug.arm32 = "res://bin/libgame.linux.template_debug.arm32.so"
linux.release.arm32 = "res://bin/libgame.linux.template_release.arm32.so"
linux.debug.arm64 = "res://bin/libgame.linux.template_debug.arm64.so"
linux.release.arm64 = "res://bin/libgame.linux.template_release.arm64.so"
linux.debug.rv64 = "res://bin/libgame.linux.template_debug.rv64.so"
linux.release.rv64 = "res://bin/libgame.linux.template_release.rv64.so"
android.debug.x86_64 = "res://bin/libgame.android.template_debug.x86_64.so"
android.release.x86_64 = "res://bin/libgame.android.template_release.x86_64.so"
android.debug.arm64 = "res://bin/libgame.android.template_debug.arm64.so"
android.release.arm64 = "res://bin/libgame.android.template_release.arm64.so"
ios.debug = "res://bin/libgame.ios.template_debug.xcframework"
ios.release = "res://bin/libgame.ios.template_release.xcframework"
web.debug.threads.wasm32 = "res://bin/libgame.web.template_debug.wasm32.wasm"
web.release.threads.wasm32 = "res://bin/libgame.web.template_release.wasm32.wasm"
web.debug.wasm32 = "res://bin/libgame.web.template_debug.wasm32.nothreads.wasm"
web.release.wasm32 = "res://bin/libgame.web.template_release.wasm32.nothreads.wasm"

现在我们可以在godot项目任意位置新建文件libgame.gdextension 并将以上代码粘贴进去,当然更建议和编译出来的库文件放在一起 现在在节点中就可以找到我们的插件GDExample​了

3.png

加入该节点,并对Sprite2d​添加Texture​,取消勾选Offset/Centered

4.png

以上就是使用vs配置 GDExtension 开发环境的简单流程了。