GameTech/Godot 4.7 互动教程
目录示例游戏
第一部分 · 入门 · 第 1 章

认识 Godot 4.7

Godot 是什么、该下载哪个版本、三种渲染器怎么选;认识项目管理器和编辑器的各个区域,弄清工程文件夹里每个文件的用途,做出第一个场景。最后介绍本教程的用法:在网页上运行示例、拖滑块改参数、下载工程。

这一章不急着写代码,先把工具认清楚:Godot 是什么样的引擎,下载哪个版本,打开以后界面上每块区域是干什么的,工程文件夹里那些文件哪些要提交、哪些可以删。最后用几分钟做出第一个能运行的场景。

先看一眼本教程的第一个示例。点击画面运行它(第一次加载约 10 MB,之后浏览器会缓存):

这是一个真正的 Godot 4.7.2 工程,被导出成了 Web 版嵌在网页里。右边的滑块直接连着游戏脚本里的变量:拖「太阳自转」,地球绕太阳转的速度就跟着变;拖「地球轨道半径」,地球离太阳的距离就跟着变。下一章会详细解释为什么"太阳自转"会让地球"公转"——这正是 Godot 节点树最核心的规则。

Godot 是什么

Godot 是一个开源、免费的游戏引擎,采用 MIT 许可证:用它做的游戏归你所有,不需要付授权费,也不用在启动画面上显示引擎标志。引擎和编辑器是同一个程序,下载下来几十 MB 的一个文件,解压就能用,不需要安装器,也不需要注册账号。

和其他引擎比,Godot 有几个明显的特点:

  • 一切都是节点(Node)。精灵、摄像机、碰撞体、按钮、计时器、声音播放器,全都是节点。节点组成一棵树,一棵树可以保存成一个场景(.tscn 文件),场景又可以作为一个节点放进别的场景里。整个游戏就是这样一层层搭起来的。第 2 章专门讲这件事。
  • 2D 是一等公民。Godot 的 2D 有独立的渲染管线和以像素为单位的坐标系,不是"把 3D 摄像机摆成正交"凑出来的。做 2D 游戏时不需要和 3D 概念打交道。
  • 自带脚本语言 GDScript。语法接近 Python,为游戏开发专门设计:向量、颜色、节点路径都是内置类型,和编辑器深度集成(自动补全、检查器里直接显示脚本变量)。也可以用 C#(需要 .NET 版)或通过 GDExtension 用 C++、Rust 等语言。
  • 文本格式的资源。场景、资源、工程设置默认都是可读的文本文件,适合用 Git 管理和对比差异。

4.7 的版本定位

Godot 4.0 在 2023 年发布,重写了渲染器、物理和 GDScript,和 3.x 不兼容。之后的 4.1、4.2……每隔几个月发布一个小版本,在 4.x 系列内保持兼容:低版本的工程可以直接用高版本打开(打开时会提示升级,升级后就不建议再用旧版本打开了)。本教程基于 4.7.2,所有示例都在这个版本里实际运行过。

你在网上看到的教程如果是 3.x 的,很多写法已经变了(比如 yield 变成了 await,KinematicBody2D 变成了 CharacterBody2D);4.0~4.3 时期的教程大多还能用,但可能缺少后来加入的功能,比如 4.4 引入的 .uid 文件、类型化字典 Dictionary[String, int]。遇到不一致时,以编辑器里按 F1 打开的内置文档为准,它永远和你手上的版本一致。

Godot 3 的工程不能直接在 4.x 里运行。用 4.x 打开 3.x 工程时,编辑器会提供一个"转换"工具,能自动改掉大部分改名的类和方法,但信号连接、yield、物理代码等仍要手工调整。建议先备份或在新分支上转换。另外,3.x 的导入缓存放在 .import/ 文件夹,4.x 改成了 .godot/,转换后旧的 .import/ 可以删掉。

标准版和 .NET 版

官网下载页上,每个平台都有两个版本:

标准版(Standard).NET 版
脚本语言GDScript(以及 GDExtension)GDScript + C#
额外依赖无需要安装 .NET SDK
导出到 Web可以目前不支持使用了 C# 的工程导出 Web
体积小大一些

.NET 版能做标准版能做的所有事,只是多了 C# 支持;反过来,标准版打不开含有 C# 脚本的工程。如果你没有非用 C# 不可的理由,选标准版。本教程全部使用 GDScript,示例也要导出到网页上运行,所以用的都是标准版。

三种渲染器:Forward+、Mobile、Compatibility

新建项目时要选一个渲染器(之后也能在「项目设置 → 渲染 → 渲染器」里改)。三者的区别在于使用的图形接口和支持的特效:

  • Forward+:面向桌面显卡,使用 Vulkan、Direct3D 12 或 Metal。功能最全,有 SDFGI 实时全局光照、体积雾、屏幕空间反射等高级效果。
  • Mobile:同样使用 Vulkan / Metal,但为手机的显卡架构做了简化,砍掉了一部分昂贵的效果,换取更低的开销。
  • Compatibility:使用 OpenGL 3.3 / OpenGL ES 3.0 / WebGL 2。功能最少,但能跑在最老的硬件和浏览器里,启动也最快。

Web 导出为什么只能用 Compatibility?因为浏览器给网页提供的图形接口是 WebGL 2,它在能力上相当于 OpenGL ES 3.0,没有 Vulkan 那样的接口可用。Godot 目前只有 Compatibility 渲染器实现了 WebGL 2 后端,所以要导出 Web,就必须用它。本教程所有示例都是这样设置的:

project.godot第 24–28 行project.godot 里的渲染器设置在工程中查看 ↗
[rendering]

renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
environment/defaults/default_clear_color=Color(0.051, 0.071, 0.125, 1)

下面这个表把常见需求和三种渲染器对应起来。点击左边的行勾选你的目标平台和想要的功能,绿色框标出的是满足全部条件的推荐选项:

做 2D 游戏、或者想同时发布到网页和手机时,直接选 Compatibility 是最省心的。2D 画面在三种渲染器下几乎没有区别。等你真的需要 Forward+ 的某个特效时再切换也不迟——切换渲染器不需要改代码,只是有些特效在另一个渲染器下会不起作用。

下载和安装

  1. 打开 https://godotengine.org/download,选你的操作系统,下载 Godot Engine(标准版)。也可以从 Steam 或 itch.io 安装,内容是一样的。
  2. Windows 和 Linux 下载的是一个压缩包,解压出来就是可执行文件,放在任何位置都能运行。macOS 下载的是一个 .app,拖进「应用程序」文件夹即可。
  3. 如果以后要导出游戏,还需要导出模板:在编辑器菜单「编辑器 → 管理导出模板」里在线下载,版本必须和编辑器完全一致(4.7.2 的编辑器配 4.7.2 的模板)。只在编辑器里运行的话不需要它。

项目管理器

启动 Godot 后首先看到的是项目管理器,它列出你电脑上的 Godot 工程。常用操作:

  • 新建:选一个空文件夹,填写项目名,选渲染器。可以勾选"版本控制元数据:Git",Godot 会自动生成一个排除了 .godot/ 的 .gitignore。
  • 导入:选择别人给你的工程里的 project.godot 文件。从本教程下载的示例工程就用这种方式打开。
  • 扫描:选一个文件夹,自动找出其中所有工程。
  • 「资源库项目」标签页里可以下载官方和社区的示例工程。

项目管理器只是一个列表。一个工程本质上就是一个包含 project.godot 的文件夹,把文件夹复制到别的电脑上,导入后就能接着做。

编辑器的各个区域

打开一个工程后进入编辑器。默认布局分成几大块,下面这个示意图按 Godot 4.7 的默认布局画出了它们。点击任意区域查看说明,点顶部的「2D / 3D / 脚本 / 游戏 / 资源库」可以切换中间区域:

刚开始最常打交道的是四个地方:场景面板里搭节点树,视口里摆位置,检查器里改属性,文件系统里管理文件。它们之间是联动的:在场景面板选中一个节点,视口里会出现它的控制柄,检查器里显示它的属性;在文件系统里把一张图片拖进视口,会自动创建一个显示它的 Sprite2D 节点。

检查器里的每个属性都对应着节点的一个变量。鼠标悬停在属性名上会显示它在代码里的名字,比如「Position」就是 position,「Rotation」就是 rotation。你在检查器里能改的,在代码里也能改;反过来,脚本里用 @export 标记的变量也会出现在检查器里。本教程网页上的滑块,做的事情和检查器一样:直接修改这些变量。

工程文件夹里有什么

Godot 工程就是一个普通文件夹,没有隐藏的数据库。下面是本章示例工程(basics)的主要内容,点击每一行查看说明,右边标出了是否需要提交到版本库:

res:// 和 user://

Godot 的代码里不用操作系统的绝对路径,而是用两个虚拟路径前缀:

  • res:// 指向工程文件夹(project.godot 所在的位置)。场景、脚本、图片都用它引用,比如 res://solar/solar.tscn。游戏导出后,这些文件被打包进 .pck,res:// 变成只读的。
  • user:// 指向一个可写的用户数据目录,存档、设置、日志都写在这里。各平台的实际位置不同(见上面浏览器里 user:// 一行),代码里不需要关心。

不要把存档写到 res://。在编辑器里运行时,写 res:// 看起来能成功(因为它就是你硬盘上的工程文件夹),但导出后的游戏里 res:// 是只读的 pck 包,写入会失败。存档一律用 user://。

project.godot

工程设置全部存在 project.godot 里,格式是普通的 ini 文本。「项目 → 项目设置」里只保存和默认值不同的项。下面是本章示例的完整配置:

project.godot第 1–32 行basics 示例的工程设置在工程中查看 ↗
; Godot 4.7 项目文件。用 Godot 4.7.x 打开本文件夹即可。

config_version=5

[application]

config/name="入门示例 Basics"
config/description="《Godot 4.7 互动教程》配套示例:场景树、信号、生命周期、变换。"
run/main_scene="res://main.tscn"
config/features=PackedStringArray("4.7", "GL Compatibility")

[autoload]

Tuning="*res://tuning.gd"
Events="*res://events.gd"

[display]

window/size/viewport_width=960
window/size/viewport_height=540
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"

[rendering]

renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
environment/defaults/default_clear_color=Color(0.051, 0.071, 0.125, 1)

[gui]

theme/custom_font="res://fonts/ui_font.ttf"

其中 run/main_scene 是按 F5 时运行的主场景;[autoload] 里的两行是"自动加载",游戏启动时会自动创建这两个节点,挂在场景树的根下面,任何脚本都能直接用名字访问它们(第 4 章会讲 Events 这个事件总线);[display] 里设置了 960×540 的设计分辨率和拉伸模式。

.godot 文件夹和 .uid 文件

.godot/ 是编辑器的缓存。你放进工程的 PNG、OGG、TTF 文件,Godot 会把它们"导入"成引擎内部更高效的格式,结果就存在 .godot/imported/ 里,原始文件旁边的 .import 文件则记录导入设置。缓存可以随时删除重建,所以不提交;.import 文件是设置,要提交。

从 4.4 开始,每个脚本(.gd)和着色器(.gdshader)旁边多了一个同名的 .uid 文件,里面只有一行形如 uid://b8x... 的唯一 ID。场景文件引用脚本时会同时记下路径和这个 ID,这样即使你在编辑器外面移动或改名了文件,Godot 也能凭 ID 找到它。场景、图片等资源的 UID 写在资源文件自身或 .import 文件里,所以只有脚本和着色器需要额外的 .uid 文件。

.uid 文件要提交到版本库,并且和对应的 .gd 放在一起。常见的坑:.gitignore 里写了 *.uid,或者在文件管理器里只移动了 .gd 没带上 .uid。结果是别人拉下代码后,场景里的脚本引用出现"无效 UID"警告。最稳妥的做法是只在 Godot 的文件系统面板里移动和重命名文件。

第一个场景

按照下面的步骤做一个会旋转的 Godot 图标,整个过程不超过五分钟:

  1. 在项目管理器里新建一个项目,渲染器选 Compatibility。
  2. 在场景面板点「2D 场景」,得到一个名为 Node2D 的根节点。
  3. 点「+」添加子节点,搜索 Sprite2D 并创建。在检查器里找到 Texture 属性,把文件系统里的 icon.svg 拖上去。
  4. 在视口里把图标拖到紫框中间。
  5. 选中 Sprite2D,点场景面板上方的"附加脚本"按钮(卷轴图标),直接确认创建。把下面的代码粘进去:
snippets/intro_first.gd第 5–13 行第一个脚本:让精灵旋转在工程中查看 ↗
@export var speed_degrees := 90.0      # 每秒转多少度;@export 让它出现在检查器里


func _ready() -> void:
	print("你好,Godot!我叫 ", name)   # 输出在编辑器底部的"输出"面板


func _process(delta: float) -> void:
	rotation_degrees += speed_degrees * delta   # delta 是距上一帧的秒数,乘上它速度才和帧率无关
  1. 按 Ctrl+S(macOS 上是 Cmd+S)保存场景,起名 main.tscn。
  2. 按 F6 运行当前场景。会弹出一个窗口,图标在旋转;底部的「输出」面板里打印出"你好,Godot!我叫 Sprite2D"。

这几行代码已经用到了 Godot 脚本最基本的结构:extends 说明这个脚本扩展的是哪种节点;_ready() 在节点准备好时调用一次;_process(delta) 每一帧调用一次,delta 是距离上一帧过了多少秒。rotation_degrees += speed_degrees * delta 的意思是"每秒转 speed_degrees 度"——乘上 delta 之后,不管游戏跑 30 帧还是 144 帧,转速都一样。这些在第 3 章会系统地讲。

回到检查器,你会发现 Sprite2D 的属性列表最上面多了一项 Speed Degrees,就是脚本里 @export 的那个变量。在检查器里改它,或者在游戏运行时改,都会影响转速。

动手试试:在上面的第一个场景里,把 Speed Degrees 改成 -360 再运行,图标应该每秒反向转一整圈。然后把 * delta 删掉再运行,图标会转得飞快而且转速取决于你的显示器刷新率——这就是"帧率相关"的移动,以后要避免。

本教程怎么用

每一章都配有可以在网页里直接运行的示例。它们不是录像,也不是用 JavaScript 模仿的,而是真实的 Godot 工程导出的 Web 版。使用方法:

  • 运行:点击示例画面。同一页面同一时间只运行一个示例,点另一个会停掉前一个。「全屏」按钮可以放大。
  • 调参:右侧(窄屏时在下方)的滑块、开关、下拉框,每一项都对应游戏脚本里的一个 @export 变量,名字标在滑块旁边。拖动后游戏里立即生效,不需要重启。改过的参数会高亮显示。
  • 实时数据:游戏每秒向网页报告几次内部数据,显示在参数下方。比如太阳系示例会报告地球的 position 和 global_position,你会看到前者一直不变、后者一直在变——下一章会解释原因。
  • 复制为 GDScript:把你改过的参数整理成 变量名 = 值 的形式,方便抄回自己的工程。
  • 下载工程:下载这个示例的完整工程,用 Godot 4.7 导入就能打开。如果你改过参数,下载的工程会带上你的修改。
  • 完整示例页:显示全部参数,并且可以浏览示例的全部源码。

示例和网页之间是怎么通信的?工程里有一个自动加载脚本 tuning.gd,它在 Web 版里监听浏览器发来的消息,收到"把 sun.spin_speed 改成 45"时,就找到对应节点,给它的 spin_speed 变量赋值。游戏脚本只需要声明哪些变量可以被网页修改:

solar/solar.gd第 28–35 行太阳系场景把参数绑定到三个天体上在工程中查看 ↗
func _ready() -> void:
	sun.position = SUN_CENTER
	Tuning.bind(sun, "sun", ["spin_speed", "body_scale"])
	Tuning.bind(earth, "earth", ["spin_speed", "distance", "detach"])
	Tuning.bind(moon, "moon", ["spin_speed", "distance"])
	Tuning.bind(self, "solar", ["show_axes", "show_trails", "show_orbits"])
	Tuning.action_triggered.connect(_on_action)
	_make_stars()

这些代码在你自己的工程里不需要。你在编辑器里调参数用检查器就够了;它只是让网页上的滑块能做检查器做的事。示例里切换小场景的「当前场景」下拉框也是同样的原理,它对应 main.gd 里的这个变量:

main.gd第 17–22 行网页上的「当前场景」下拉框对应这个 @export 变量在工程中查看 ↗
## 当前显示哪个小场景。网页上切换时,Tuning 会直接给它赋值,setter 负责换场景。
@export_enum("太阳系", "信号实验室", "生命周期") var scene := "太阳系":
	set(value):
		scene = value
		if is_node_ready():
			_load_scene()

变量后面的 set(value): 是一个 setter:每次给 scene 赋值时都会执行它,在这里用来切换场景。setter 的写法第 3 章会讲。

动手试试:运行本章开头的示例,先把「太阳自转」拖到 0,地球会停在原地不再公转,但它自己和月亮还在转。再把「地球自转」也拖到 0,月亮也停止绕地球转了。最后点「复制为 GDScript」,看看网页把你的修改整理成了什么样子。

小测验

你想做一个能在浏览器里玩的游戏,新建项目时应该选哪个渲染器?

  1. Forward+,因为它功能最全
  2. Mobile,因为浏览器和手机差不多
  3. Compatibility

浏览器只提供 WebGL 2,Godot 只有 Compatibility 渲染器能运行在 WebGL 2 上。Forward+ 和 Mobile 都需要 Vulkan / D3D12 / Metal。

下面哪个不应该提交到 Git?

  1. player.gd.uid
  2. .godot/ 文件夹
  3. icon.svg.import
  4. project.godot

.godot/ 是编辑器缓存,删掉会自动重建。.uid 和 .import 文件都记录着重要信息(脚本的唯一 ID、导入设置),必须提交。

游戏要保存玩家的存档,应该写到哪里?

  1. user://save.json
  2. res://save.json
  3. 和游戏可执行文件同一个文件夹

导出后 res:// 是打包好的只读资源。user:// 是 Godot 为每个游戏准备的可写目录,在所有平台(包括 Web)上都能用。

小结

  • Godot 是 MIT 许可的开源引擎,引擎和编辑器是同一个小程序。没有 C# 需求就用标准版。
  • 三种渲染器:Forward+ 功能最全,Mobile 面向手机,Compatibility 兼容性最好;导出 Web 只能用 Compatibility。
  • 编辑器里最常用的四块:场景面板、视口、检查器、文件系统。检查器里的属性就是节点的变量。
  • 工程就是一个带 project.godot 的文件夹。.godot/ 不提交;.uid 和 .import 要提交。资源用 res:// 引用,运行时写文件用 user://。

下一章从这个太阳系示例出发,讲 Godot 最核心的概念:节点、场景树和场景实例化。