mcpField
B
bevy-input-actions

bevy-input-actions

github.com/chrisgliddon开发2668 次安装9 周前更新
代码仓库

关于 bevy-input-actions

面向 Bevy 0.19 游戏开发的输入动作技能,指导将键鼠、触屏和手柄输入转换为可重绑定的逻辑动作,并处理固定步模拟、设备与焦点状态。

主要功能

  1. 01设备无关的动作与重绑定
  2. 02稳定序列化动作 ID
  3. 03多手柄连接与玩家分配
  4. 04按设备校准摇杆输入
  5. 05固定步输入缓冲与回放
  6. 06鼠标捕获和焦点丢失策略

适用场景

  1. 01实现可重绑定的游戏操作
  2. 02处理手柄热插拔和多玩家输入
  3. 03将帧输入传递给固定步模拟
  4. 04避免窗口失焦后的输入卡滞

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/chrisgliddon/bevy-skills --skill bevy-input-actions

安装后在 Claude Code 中输入/bevy-input-actions确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
action-model-and-rebinding.md
fixed-step-buffering.md
gamepads-and-platforms.md

详细介绍

Bevy 0.19 — 输入动作

何时使用此技能

  • 游戏玩法需要与设备无关、可持久化、可重新绑定的动作和提示。
  • 控制器可能热插拔或重新排序,或者多个玩家/设备共用输入。
  • 鼠标捕获、焦点丢失、Steam Deck 或自适应硬件需要统一策略。
  • 帧作用域的边沿/运动必须驱动确定性的 FixedUpdate 模拟。

游戏玩法只使用逻辑动作,绝不直接使用原始按键或硬编码的控制器实体。 只需将 Bevy 的帧输入转换为一次动作状态,然后从该状态驱动表现层和固定步长模拟。

标准模式

Bevy 在 PreUpdate 的 InputSystems 中更新原始输入。在该集合之后运行转换器, 这样 ButtonInput、Gamepad、输入消息和累计鼠标运动就能反映当前帧:

use bevy::{input::InputSystems, prelude::*};

fn install_input(app: &mut App) {
    app.init_resource::<ActionBuffer>().add_systems(
        PreUpdate,
        translate_physical_input.after(InputSystems),
    );
}

#[derive(Resource, Default)]
struct ActionBuffer;

fn translate_physical_input(mut _actions: ResMut<ActionBuffer>) {}
keyboard / mouse / touch / Gamepad entities / Steam Input
                     |
                     v
        physical bindings + device calibration
                     |
                     v
       active action set/context + conflict policy
                     |
                     v
       frame action state + ordered transition queue
              |                         |
        Update/UI consumers      fixed-tick bridge

使用稳定的序列化动作 ID,例如 gameplay.jump、menu.confirm 和 camera.look。绑定、标签、提示、存档数据和分析数据都引用这些 ID; Rust 枚举判别值和目录顺序不能作为持久化契约。

如果某个边沿的精确设备流内顺序很重要,请将底层键盘、鼠标或游戏手柄消息转换为有序队列。 单个 just_pressed 布尔值无法表示两次状态转换及其顺序。按住状态和经过滤波的轴值 可以存储为最新值。

在 Bevy 0.19 中,游戏手柄是实体

fn inspect_gamepads(gamepads: Query<(Entity, &Gamepad)>) {
    for (entity, gamepad) in &gamepads {
        let move_x = gamepad.get(GamepadAxis::LeftStickX).unwrap_or(0.0);
        let jump_started = gamepad.just_pressed(GamepadButton::South);
        let _sample = (entity, move_x, jump_started);
    }
}

使用 GamepadConnectionEvent 处理连接变化;如果连接、按键和轴变化之间的相对顺序很重要, 则使用 GamepadEvent。将活跃玩家分配单独存储,不要与绑定混为一谈。ECS Entity 是 实时设备句柄,不是稳定的设备标识或存档文件键。

通过每个设备的 GamepadSettings 组件配置滤波。只应用一次内死区、可选的外部校准、 响应曲线和最终限幅。不要在游戏玩法代码中再次隐式应用死区。

注意事项:帧输入不等于固定步长输入

原始输入的作用域是帧,而固定步长模拟在该帧中可能运行零次、一次或多次。因此:

  • 保留有序的按下/释放状态转换,直到某个固定步长模拟步消耗它们;
  • 累积相对运动,直到同一个模拟步;
  • 在第一个可用的模拟步中,将状态转换和相对运动各消费一次;
  • 将按住的按键和绝对轴值复制到每个固定步长模拟步;
  • 绝不要在每次 FixedUpdate 迭代中独立重新读取 just_pressed 或 AccumulatedMouseMotion。

对于回滚/网络模拟,请将桥接输出转换为按模拟刻编号的显式命令帧,并保留以供重放。

鼠标捕获与焦点

通过主窗口的 CursorOptions 捕获鼠标:当游戏玩法接管视角输入时,隐藏光标并请求 CursorGrabMode::Locked。焦点丢失时,暂停或将游戏玩法输入置为中性、释放捕获、 合成所需的动作释放事件,并清除相对运动。只有在用户有意操作后才重新捕获; 绝不要仅因焦点恢复就困住指针。

焦点丢失时,Bevy 会释放键盘状态,而游戏手柄状态不受窗口焦点影响。你的动作层仍需采用 统一策略,避免游戏玩法动作卡住或意外触发。

选择相关深入指南

问题阅读
稳定动作、绑定语法、上下文、重新绑定和冲突动作与重新绑定
设备分配、热插拔、死区、Steam Deck 和自适应硬件游戏手柄与平台
边沿队列、鼠标累积、零次/多次固定步长模拟、回滚固定步长缓冲

审查清单

  • 每项游戏操作都可通过命名动作绑定,包括菜单和无障碍操作路径;关键操作应提供组合键或长按之外的替代方式。
  • 提示词应解析当前生效的绑定和设备图标,而不是直接写出按键名称。
  • 一个控制器断开连接时,不会在没有提示的情况下将其玩家转移到另一个控制器。
  • 在两个固定更新帧之间发生的按下和释放事件会按顺序恰好传递一次。
  • 鼠标移动不会在零更新帧时丢失,也不会在追赶更新帧时被重复处理。
  • 焦点丢失不会导致动作保持按下状态或指针捕获状态卡住。
  • 使用真实硬件和已保存的重新绑定设置,对 Steam Deck 和自适应控制器进行测试。

另请参阅

评论

支持 Markdown