为你的游戏编程
本页面为自动翻译,可能包含错误。如果发现问题,请通过“编辑此页面”链接帮助修正。
您的第一个组件
在项目的 assets/ 文件夹内创建一个 .zig 文件。编辑器通过扫描这些文件来发现组件。每个组件是一个带有 is_component 标记的普通 Zig 结构体:
const engine = @import("engine");
pub const Rotator = struct {
pub const is_component = true;
speed: f32 = 90.0,
pub fn update(self: *Rotator, time: engine.Time) void {
// rotation API will be applied here
_ = self;
_ = time;
}
};
组件发现规则:
- 结构体必须是
pub的,且名称以大写字母开头。 pub const is_component = true;标记它为可发现。设置为false可临时排除。- 组件类型名称在项目中必须是唯一的。
- 支持的字段类型:
f32、i32、bool、engine.Vec3、engine.GameObjectRef、engine.ComponentRef、engine.AssetRef。
保存文件后,点击资源浏览器中的刷新,然后在层级中选择一个节点,从添加组件 ▾ 中选择您的组件。
生命周期钩子
所有钩子都是可选的:
| 钩子 | 调用时机 |
|---|---|
awake(self) |
对象首次加载时 |
enable(self) |
对象变为活跃时 |
start(self) |
场景开始运行时 |
update(self, time: engine.Time) |
每帧 |
disable(self) |
对象变为非活跃时 |
destroy(self) |
对象被销毁时 |
每个钩子也接受 frame: engine.Frame 参数,如果您需要输入、服务或完整的场景上下文——请改用 update(self, frame: engine.Frame)。
有关节点生命周期和所有可用钩子的更完整说明,请参阅组件页面。
使用 engine.Time
engine.Time 结构体提供帧 timing 信息:
| 字段 | 类型 | 含义 |
|---|---|---|
.delta |
f32 |
自上一帧以来的秒数 |
.elapsed |
f32 |
自场景启动以来的总秒数 |
.frame |
u64 |
帧计数器 |
示例——一个 FPS 计数器:
const std = @import("std");
const engine = @import("engine");
pub const FpsDisplay = struct {
pub const is_component = true;
_timer: f32 = 0,
pub fn update(self: *FpsDisplay, time: engine.Time) void {
self._timer += time.delta;
if (self._timer >= 1.0) {
self._timer -= 1.0;
const fps = if (time.delta > 0) 1.0 / time.delta else 0.0;
std.debug.print("FPS: {d:.0}\n", .{fps});
}
}
};
在检查器中自定义字段值
任何具有默认值的公共字段都会在检查器面板中变为可编辑的控件。选择一个节点,展开其组件,然后直接编辑:
f32→ 带有箭头步进按钮的数字字段。i32→ 整数字段。bool→ 复选框。engine.Vec3→ 三轴向量字段,带有标记的轴。engine.GameObjectRef→ 拖放目标——从层级中拖拽一个节点。engine.ComponentRef→ 拖放目标——引用另一个组件。engine.AssetRef→ 拖放目标——引用任何资源。
以 _ 为前缀的字段(如 _timer)被视为私有运行时状态,在检查器中隐藏。
要为每个实例设置不同的默认值,请在添加组件后在检查器中更改它们——编辑器会在场景文件中记录覆盖。
示例
const engine = @import("engine");
pub const Patrol = struct {
pub const is_component = true;
speed: f32 = 2.5,
target: engine.GameObjectRef = .{},
loop: bool = true,
};
将 Patrol 添加到节点后,检查器会显示 speed、target 和 loop。将 speed 调整为 5.0,将一个节点拖入 target,并取消勾选 loop——全都无需触碰代码。