SuperAPI AI 工具集

bevy-adapt-3d-to-2d

编程与开发

查看项目

更新于 10-16 06:08

技能介绍

用途

本技能用于在 Bevy 引擎中把一款原本按 3D 设计的游戏改为以 2D 方式渲染。适用场景是:3D 设计需要以精灵(sprite)或公告板(billboard)形式呈现。其原则是玩法组件保持不变,渲染组件发生改变。

主要能力

  • 绘制:在公告板足够的情况下,把网格与 PBR 材质实体的渲染部分替换为 Sprite。
  • 相机:使用来自 bevy-camera-systems 的 Camera2d。
  • 灯光:无光照的精灵不需要 3D 灯光实体;不要在玩法代码中保留聚簇光照(clustered-light)的假设。
  • 绘制顺序:用一个自行存储的 DrawOrder 组件,再写入 Transform。

使用方式

依赖声明为:

[dependencies]
bevy = "0.20"

玩法组件保留在实体上,移除 3D 渲染组件,插入 Sprite,并以 Camera2d 作为视图。示例代码:

#[derive(Component)]
struct Actor;

#[derive(Component)]
struct DrawOrder(f32);

fn spawn_flat_view(mut commands: Commands) {
    commands.spawn(Camera2d);
}

fn present_as_sprites(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    actors: Query<(Entity, &DrawOrder), With<Actor>>,
) {
    let image = asset_server.load("actors/hero.png");
    for (entity, order) in &actors {
        commands
            .entity(entity)
            .remove::<Mesh3d>()
            .remove::<MeshMaterial3d<StandardMaterial>>()
            .insert((
                Sprite {
                    image: image.clone(),
                    custom_size: Some(Vec2::new(64.0, 64.0)),
                    ..default()
                },
                Transform::from_xyz(0.0, order.0, 0.0),
            ));
    }
}

新角色也可以直接以扁平方式生成,玩法系统查询的仍是同一个 Actor 组件:

#[derive(Component)]
struct Actor;

fn spawn_sprite_actor(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        Actor,
        Sprite {
            image: asset_server.load("actors/hero.png"),
            color: Color::WHITE,
            ..default()
        },
        Transform::from_xyz(0.0, 0.0, 0.0),
    ));
}

fn face_motion(mut actors: Query<(&Transform, &mut Sprite), With<Actor>>) {
    for (transform, mut sprite) in &mut actors {
        sprite.flip_x = transform.translation.x < 0.0;
    }
}

在没有 3D 相机的情况下,依据存储的顺序对精灵排序。较高的 DrawOrder 映射到较高的 Y,使 2D 相机在俯视布局中更晚绘制它:

#[derive(Component)]
struct DrawOrder(f32);

fn apply_draw_order(mut sprites: Query<(&DrawOrder, &mut Transform), With<Sprite>>) {
    for (order, mut transform) in &mut sprites {
        transform.translation.y = order.0;
    }
}

专家知识要点

目标为 Bevy 0.20+。核心 ECS 类型包括:Component、Resource、Query、Commands、Startup、Update、Fixed / FixedMain(bevy::time)、.chain()、Plugin、DefaultPlugins、MinimalPlugins。消息与观察者属于一个所有权槽位,其 API 参见 bevy-events-messaging。除非用 .chain() 对冲突的系统排序,否则系统并行运行。

状态所有权:

  • 单个实体上的数据:由 Component 持有,一个系统通过 Query 修改,运行于 Update 或 FixedMain。
  • 整个应用的一个值:由 Resource 持有,一个系统修改,在 Startup 插入,随后由读取它的调度使用。
  • 生成:由 Commands 负责,生成系统执行;初始世界在 Startup,运行时生成在后续调度。
  • 不能竞态的顺序:由 .chain() 约束,仅作用于被链式连接的系统,位于同一调度。
  • 插件边界:由 Plugin 负责,build 注册系统与资源,在应用运行前完成。

借用规则:两个系统若都可变查询同一组件,必须排序(.chain())或拆分,使只有一个写入。无关系统保持并行。这是 ECS 页面规则,并非对系统集 API 的猜测。

决策表:

  • 需要逐实体数据:用 Component + Query,不要用存放在世界之外的普通结构体。
  • 需要应用级配置或时钟:用 Resource,不要把值复制到每个实体。
  • 需要稳定的模拟步长:用 FixedMain 与 Fixed 时钟,不要把模拟绑定到原始帧 Update。
  • 需要启动时生成:在 Startup 中用 Commands,不要从渲染系统生成。
  • 需要非共享状态的跨系统通知:使用 bevy-events-messaging 中的消息或观察者槽位,不要在本文件中新造事件类型。
  • 需要文档集之外的 API:先查官方文档,不要使用编造的 crate 或 API。

所有权表可加载 references/ecs-ownership.md。

禁止事项

  • 不要在文档 URL 中固定 /0.20.0/。原因:链接保持指向最新版;0.20 目标只在正文中说明一次。
  • 不要从两个无序系统可变查询同一组件。原因:除非用 .chain() 排序,调度会并行运行系统。
  • 不要在此处编造物理、导航、网络或 XR crate。原因:本技能只命名有文档记录的 Bevy crate 与模块。
  • 不要在已变为精灵的实体上残留 Mesh3d 或 MeshMaterial3d。原因:同一实体上的两条渲染路径会争夺同一个 transform。
  • 不要使用编造的 API 或未命名的第三方 crate 作为选定求解方案。原因:Bevy 代码保持惯用 ECS,且只使用有文档记录的 Bevy API。

参考

bevy-master 上的库固定版本保持 0.20.0,永久链接保持不带版本。

官方文档:

  • Assets - 官方资源目录。未选择第三方 crate。
  • Examples - 最新分支上的示例树。
  • 2D examples - 精灵与相机示例。
  • ECS - Component、systems、Query、Startup、Update 与 .chain()。
  • Plugins - Plugin、DefaultPlugins、MinimalPlugins 与 add_plugins。

相关技能:

前置:bevy-master(枢纽与调度)、bevy-ecs-composition(组件与系统)、bevy-camera-systems(Camera2d)、bevy-2d-animation(精灵剪辑)。

互补:bevy-adapt-2d-to-3d(反向适配)。

下游 / 消费者:暂无。

主技能:bevy-master(Bevy 路由)。