入力

このページは自動翻訳されており、誤りが含まれる場合があります。誤りを見つけた場合は「このページを編集」リンクからご協力ください。

Turian の入力システムは、名前付きアクションを通じて物理デバイスとゲームロジックを分離します。アクションを .inputactions アセットで定義すると——キーボード、マウス、ゲームパッドのすべてのバインディングが同じアクション名にマッピングされます——スクリプトは「jump アクションが押されているか」だけを問い合わせ、「Space が押されているか」を尋ねることはありません。


クイックスタート

1. 入力アクションアセットを作成する

アセットブラウザで、右クリック → 作成 → 入力アクション。選択したフォルダにデフォルトの .inputactions ファイル(ZON 形式)が書き込まれます。

ファイルをダブルクリックして入力アクションエディターを開きます。

2. アクションを定義する

エディターにはアクションのリストが表示されます。各アクションには以下があります:

  • 名前 — スクリプトが使用する文字列(例:jumpmovelook)。
  • 種類button(オン/オフ)、axis(1D −1…+1)、または vector(2D、x/y)。
  • ロール — 軸には Positive/Negative、ベクターには Right/Left/Up/Down、ボタンには Buttons。各ロールは最大4つのバインディングを保持できます。

各バインディングに対して、デバイスコードを選択します:

デバイス コード例
key aspaceleft_shiftleft_ctrl
mouse rightleftmiddle
gamepad_button southeastleft_shoulderleft_trigger
gamepad_axis left_xleft_yright_xright_yleft_triggerright_trigger

gamepad_axis の場合、+ チェックボックスでその軸の正方向(スティック右、トリガー押下)を選択します。チェックを外すと負方向になります。

保存をクリックして ZON ファイルを書き込み、プロジェクトに再クックします。

3. アセットをパッケージ化する

ゲームローダーはプロジェクト内のすべての .inputactions アセットを自動的に発見します——コードは不要です。アセットは起動時に共有の engine.Input に適用されます。


スクリプトでアクションを読み取る

スクリプトは update を通じて engine.Frame コンテキストを受け取ります。frame.input*const engine.Input です:

const engine = @import("engine");

pub const PlayerController = struct {
    pub const is_component = true;

    speed: f32 = 5.0,

    pub fn update(self: *@This(), frame: engine.Frame) void {
        const input = frame.input;
        const dt    = frame.time.delta;
        const t     = frame.transform;

        // ボタンアクション — デジタルオン/オフ
        if (input.wasPressed("jump")) {
            // 立ち上がりエッジのみ
        }

        // 軸アクション — 1D 連続値
        const throttle = input.axis("throttle"); // -1..+1

        // ベクターアクション — 2D(例:WASD / 左スティック)
        const move = input.vector("move"); // .x = 右, .y = 前
        t.position.x += move.x * self.speed * dt;
        t.position.z += move.y * self.speed * dt;
    }
};

アクションクエリ API

メソッド 戻り値 意味
isPressed(name) bool アクション値 ≥ しきい値(押下中)
wasPressed(name) bool このフレームでしきい値を超えた
axis(name) f32 1D 値、−1…+1、デッドゾーン付き
vector(name) engine.Vector2 2D 値、単位円にクランプ

バインディングがキー、マウスボタン、ゲームパッドスティックのいずれであっても、4つすべてのメソッドは同じように動作します——アクションの種類は、どのクエリが意味的に適切かを決定するだけです。


生デバイスクエリ

デバイス固有の状態が必要な UI やデバッグコードのために、frame.input は生のクエリも公開します:

// キーボード
if (input.isKeyDown(.space)) { ... }
if (input.wasKeyPressed(.a)) { ... }

// マウス
const delta = input.mouseDelta(); // このフレームの .x / .y ピクセル
const wheel = input.wheelDelta(); // このフレームのスクロールティック
if (input.isMouseDown(.right)) { ... }

// ゲームパッド
const lx = input.gamepadAxis(.left_x); // -1..+1
if (input.isGamepadButtonDown(.south)) { ... }

例:フリーフライカメラ

サンプルプロジェクトには FreeflyCamera.zig が含まれており、同じアクション名を使用してキーボード+マウスとゲームパッドの両方からノークリップカメラを操作します:

move        — WASD / 左スティック
look_axis   — 右スティック(アナログ、フレームレート非依存)
ascend      — Space / ゲームパッド A / 右トリガー
descend     — LShift / ゲームパッド B / 左トリガー
boost       — LCtrl / 左ショルダー
look        — 右マウスを押しながらマウスデルタで視点移動

スクリプトはアクションのみを読み取ります——キーコードには一切言及しません。player-controls.inputactions 内のすべてを再バインドしても、FreeflyCamera.zig に触れる必要はありません。


ランタイム再バインド

エンジンは、ゲーム内の「キーを押して再バインド」メニュー用に2つの関数を公開しています:

// 設定メニューの更新内で:
if (frame.input.captureBinding()) |binding| {
    // ユーザーが何かを押した——適用する
    _ = frame.input.rebind("jump", .pos, 0, binding);
}

captureBinding() は、押下しきい値を超えた最初の新しく押されたキー、マウスボタン、ゲームパッドボタン、またはゲームパッド軸を返します。rebind は、アクション名、ロール(.pos/.neg/.up/.down)、インデックスによってバインディングを置換または追加します。

永続化: 再マップしたバインディングをセッション間で保存するには、設定システムが必要です(問題 #13、未実装)。進捗は問題 #42 で追跡しています。


engine.Frame リファレンス

第2パラメータを受け取るすべてのライフサイクルフックは engine.Frame を受け取ります:

pub fn update(self: *@This(), frame: engine.Frame) void
pub fn start(self: *@This(),  frame: engine.Frame) void
// awake、enable、disable、destroy も frame を受け入れ可能
フィールド 意味
frame.time engine.Time デルタ、経過時間、フレームカウンター
frame.input *const engine.Input アクションクエリ + 生デバイス状態
frame.transform *engine.Transform このオブジェクトの位置/回転/スケール
frame.objects []engine.SceneNode シーン内のすべてのオブジェクト
frame.services *engine.Services ユーザー登録サービスレジストリ

frame.service(MyService) を使用して、型指定された ?*MyServiceframe.services から検索します。

下位互換性のために、従来の update(self, time: engine.Time) シグネチャも引き続きサポートされています。


← すべてのドキュメント このページを編集