Godot 之主循环实现分布于多层架构之中,各有其责。
一、引擎主循环(驱动层)
文件:main/main.cpp
关键函数:Main::iteration()(第 4917 行)
此函数乃引擎主循环之核心驱动,每一次调用即为一帧。其职责包括:
- 计算帧间时间(delta time)
- 处理输入事件
- 驱动主循环(
MainLoop::process()) - 更新音频服务器
- 渲染帧
// main/main.cpp 第 4917 行
bool Main::iteration() {
GodotProfileZone("Main::iteration");
iterating++;
const uint64_t ticks = OS::get_singleton()->get_ticks_usec();
// ... 帧逻辑 ...
}
二、主循环抽象接口(接口层)
文件:core/os/main_loop.h
关键类:MainLoop
此类定义主循环之抽象接口,供各种具体实现继承:
// core/os/main_loop.h 第 36-72 行
class MainLoop : public Object {
GDCLASS(MainLoop, Object);
protected:
static void _bind_methods();
GDVIRTUAL0(_initialize)
GDVIRTUAL1R(bool, _physics_process, double)
GDVIRTUAL1R(bool, _process, double)
GDVIRTUAL0(_finalize)
public:
virtual void initialize();
virtual bool physics_process(double p_time);
virtual bool process(double p_time);
virtual void finalize();
};
三、游戏主循环(应用层)
文件:scene/main/scene_tree.cpp
关键类:SceneTree(继承自 MainLoop)
关键函数:SceneTree::process()(第 688 行)
此乃游戏运行时之实际主循环,负责:
- 节点树之
process()与physics_process()调用 - 输入事件分发
- 组(Group)通知
- 场景切换管理
- 固定时间步长插值(FTI)
// scene/main/scene_tree.cpp 第 688 行
bool SceneTree::process(double p_time) {
// 固定时间步长插值更新
if (get_scene_tree_fti().is_enabled()) {
flush_transform_notifications();
get_scene_tree_fti().frame_update(get_root(), true);
}
// ... 处理节点、输入、组等 ...
}
四、调用关系总览
OS::run() // 平台层:启动程序
└─> Main::iteration() // 引擎层:每一帧调用一次
└─> MainLoop::process() // 抽象接口层
└─> SceneTree::process() // 游戏层:实际处理逻辑
└─> Node::process() // 节点层:递归调用各节点
五、Editor 主循环
Editor 运行时,主循环仍由 Main::iteration() 驱动,然其 MainLoop 实现为 Editor 特有之循环逻辑,位于 editor/editor_node.cpp 中。
六、总结
| 层次 | 文件 | 关键函数/类 | 职责 |
|---|---|---|---|
| 引擎驱动层 | main/main.cpp | Main::iteration() | 帧循环驱动、时间计算、输入处理 |
| 抽象接口层 | core/os/main_loop.h | MainLoop | 定义主循环接口 |
| 游戏应用层 | scene/main/scene_tree.cpp | SceneTree::process() | 节点树更新、输入分发、场景管理 |
| Editor 层 | editor/editor_node.cpp | Editor 主循环 | Editor 特有逻辑 |