godot-rust(gdext)创建项目

2 阅读5分钟

简介

本文以Hello World - godot-rust中文文档内容为蓝本撰写。如果你对rust、godot等内容比较生疏或感到疑惑,可以先阅读godot-rust入门文档。本文操作均在Windows上执行。

正文

新建游戏项目

在你喜欢的任意一个路径位置新建项目文件夹,为游戏起一个名字:\ 无标题.jpg
本文使用“dodge-the-creeps-2d”。

新建godot项目

使用godot-rust,godot需要4.1或者更高版本,你可以在godot的官网上找到需要的资源。本文使用的godot的版本为4.5.1,下载后为.zip压缩文件,解压可直接运行无需安装。
启动godot,在启动入口点击创建新建godot项目1.jpg
新建项目窗口中,将项目路径选择到你刚刚创建好的游戏项目文件夹下,并填写项目名称。本文使用“godot”:
新建godot项目2.jpg
其他配置不变,创建项目。操作完成后你的游戏项目结构看上去应该像这样:

📂 dodge-the-creeps-2d
│ 
├—— 📂 godot

新建rust项目

使用cargo来创建rust项目,在命令行中定位到你的游戏项目文件下,本文中即为“dodge-the-creeps-2d”文件夹,使用cargo new命令创建,现在先别急着按回车。

cargo new {YourCrate} --lib

为你的rust项目起一个名字,替换掉上述代码里的“{YourCrate}”,本文使用“rust”。
按下回车确认执行创建,此时你的游戏项目结构看上去应该像这样:

📂 dodge-the-creeps-2d
│
├—— 📂 godot
│
├—— 📂 rust

打开Cargo.toml文件进行补充:

[package]
name = "rust"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"] # 将此crate编译为动态C库 (dynamic C library).

在命令行中定位到rust项目文件下,执行cargo add命令将gdext添加到项目中:

cargo add godot

连接godot和rust

在godot项目文件夹下新建文件,并修改成.gdextension后缀,本文使用rust.gdextension为文件名,此时你的项目文件结构看上去应该像这样:

📂 dodge-the-creeps-2d
│
├—— 📂 godot
│   ├——📄 rust.gdextension
│
├—— 📂 rust

.gdextension文件告诉 Godot 如何加载您的编译后的 Rust 扩展,它包含动态库的路径以及初始化它的入口点(函数)。

.gdextension文件内容完整的填写方式如下:

[configuration]
entry_symbol = "gdext_rust_init"
compatibility_minimum = 4.1
reloadable = true

[libraries]
linux.debug.x86_64 =     "res://../rust/target/debug/lib{YourCrate}.so"
linux.release.x86_64 =   "res://../rust/target/release/lib{YourCrate}.so"
windows.debug.x86_64 =   "res://../rust/target/debug/{YourCrate}.dll"
windows.release.x86_64 = "res://../rust/target/release/{YourCrate}.dll"
macos.debug =            "res://../rust/target/debug/lib{YourCrate}.dylib"
macos.release =          "res://../rust/target/release/lib{YourCrate}.dylib"
macos.debug.arm64 =      "res://../rust/target/debug/lib{YourCrate}.dylib"
macos.release.arm64 =    "res://../rust/target/release/lib{YourCrate}.dylib"

注意,根据你使用的操作系统来使用对应的配置
本文在windows上实现,因此只保留windows对应配置。
替换配置中的“{YourCrate}”为“rust”后(即你的rust项目名称),本文的rust.gdextension内容如下所示。

[configuration]
entry_symbol = "gdext_rust_init"
compatibility_minimum = 4.1
reloadable = true

[libraries]
windows.debug.x86_64 =   "res://../rust/target/debug/rust.dll"
windows.release.x86_64 = "res://../rust/target/release/rust.dll"

这里直接列出原文档的配置详细说明供研究参考,进一步的内容请参考教程原文

[configuration]部分应照原样复制

  • entry_symbol是指gdext暴露的入口点函数。我们选择"gdext_rust_init",这是gdext的默认值(但如果需要,可以配置)。
  • compatibility_minimum指定了扩展所需的最低 Godot 版本。使用低于该版本的Godot打开项目将导致扩展无法运行。
    • 如果您要构建一个供他人使用的插件,请尽量将此版本设置得尽可能低,以实现更广泛的生态系统兼容性,但这可能会限制您使用的功能。
  • reloadable指定当编辑器窗口失去焦点后再恢复时,应重新加载扩展。有关更多详情,请参阅 Godot issue #80284
    • 如果 Godot 崩溃,您可能需要尝试关闭或移除此设置。

[libraries] 部分应根据您的动态 Rust 库的路径进行更新。

  • 左侧的键是Godot项目的构建目标平台。
  • 右侧的值是你的动态库的文件路径。
    • res:// 前缀表示文件路径是相对于Godot目录的,无论您的.gdextension文件位于何处。您可以在 Godot 资源路径 中了解更多。
    • 如果您记得文件结构,godot项目文件夹rust项目文件夹是兄弟关系,因此我们需要回到上一级目录才能访问 rust
  • 如果您计划将项目导出到其他平台,您可以为多个平台添加配置。 至少,您需要为当前操作系统的debug模式配置路径。

通常godot会自动配置gdext,你无需手动编写,但总有例外:

在您第一次打开 Godot 编辑器时,会自动生成一个名为res://.godot/extension_list.cfg的文件。 此文件列出了项目中注册的所有扩展。如果该文件不存在,您也可以手动创建它,仅包含到你的.gdextension 文件的 Godot 路径:res://{YourCrate}.gdextension

本文中res://.godot/extension_list.cfg的文件内容为:

res://rust.gdextension

编写rust入口

到目前为止你已经成功地将godot-rust搭建了起来,但你会观察到在godot编辑器输出中提示有和.gdextension有关的错误: .gdextension错误 回忆之前rust.gdextension配置内容:

windows.debug.x86_64 =   "res://../rust/target/debug/rust.dll"
windows.release.x86_64 = "res://../rust/target/release/rust.dll"

此时项目还没有对rust进行编译,因此rust.dll根本不存在。编译rust之前,我们需要把lib.rs文件内容替换成以下模板:

use godot::prelude::*;

struct {YourRustEntryName};

#[gdextension]
unsafe impl ExtensionLibrary for {YourRustEntryName} {}

为你的rust入口起个名字替换掉“{YourRustEntryName}”,本文使用“DodgeTheCreeps2d”,与游戏项目名称保持一致,因此本文的lib.rs文件内容为:

use godot::prelude::*;

struct DodgeTheCreeps2d;

#[gdextension]
unsafe impl ExtensionLibrary for DodgeTheCreeps2d {}

下面是原文档的说明:

这里有几个要点:

  • prelude模块从godot crate引入作用域。该模块包含了 gdext API 中最常用的符号。
  • 定义一个名为 MyExtension 的结构体。它只是一个类型标记,没有数据或方法,您可以根据需要命名它。
  • 为该类型实现 ExtensionLibrary trait,并用 #[gdextension] 属性标记。

最后这一点声明了实际的 GDExtension 入口点,proc-macro 属性会处理底层的细节。

保存lib.rs,执行cargo build

cargo build

godot 4.5 版本会热重载rust.dll的内容,此时godot编辑器内依然会看到异常提示,但此时gdext的入口已经完成加载:

godot编辑器提示

参考

  1. Hello World - godot-rust中文文档
  2. 渐进式教程 — Godot Engine (4.5) 简体中文文档