ゲームのプログラミング
最初のコンポーネント
プロジェクトの 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 構造体はフレームタイミング情報を提供します:
| フィールド | 型 | 意味 |
|---|---|---|
.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→ ラベル付きの 3 軸ベクターフィールド。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 のチェックを外します。すべてコードに触れることなく行えます。