You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bevy 2D游戏缩放问题:改用Camera3dBundle后Sprite消失

Bevy 2D游戏中3D相机导致Sprite消失的问题及解决办法

你在Bevy 2D游戏中尝试用Camera3dBundle替代Camera2dBundle实现缩放,结果场景中的Sprite消失了,核心问题出在2D渲染对象与3D相机的渲染管道不兼容,以及对正交投影缩放能力的误解。

问题原因

  • SpriteBundle属于2D渲染实体,默认只会被**2D相机(使用OrthographicProjection)**捕获渲染,3D相机启用的是独立的3D渲染管道,无法识别2D渲染层的内容。
  • 你误以为OrthographicProjection无法满足缩放需求,实际上正交投影可以通过调整scale参数实现平滑缩放,完全不需要切换到透视投影。

方案一:用OrthographicProjection实现2D缩放(推荐)

这是Bevy 2D游戏的标准做法,直接修改正交相机的缩放参数即可:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup)
        .add_system(zoom_in_out)
        .run();
}

fn setup(mut commands: Commands) {
    // 配置带自定义正交投影的2D相机
    commands.spawn_bundle(Camera2dBundle {
        projection: OrthographicProjection {
            scale: 1.0, // 初始缩放比例,值越小视图越大
            ..Default::default()
        },
        ..Default::default()
    });

    commands.spawn_bundle(SpriteBundle {
        sprite: Sprite {
            custom_size: Some(Vec2::new(50., 50.)),
            color: Color::BLUE,
            ..Default::default()
        },
        ..Default::default()
    });
}

// 通过修改正交投影的scale实现缩放
pub fn zoom_in_out(mut query: Query<&mut OrthographicProjection, With<Camera>>, time: Res<Time>, input: Res<Input<KeyCode>>) {
    for mut projection in query.iter_mut() {
        // 按Z键放大,X键缩小
        if input.pressed(KeyCode::Z) {
            projection.scale -= 0.5 * time.delta_seconds();
            projection.scale = projection.scale.max(0.1); // 限制最小缩放
        }
        if input.pressed(KeyCode::X) {
            projection.scale += 0.5 * time.delta_seconds();
            projection.scale = projection.scale.min(5.0); // 限制最大缩放
        }
    }
}

方案二:强制让3D相机渲染Sprite(不推荐,仅作演示)

如果一定要用3D相机,需要将Sprite转换为3D可识别的渲染实体,比如使用Mesh2dBundle并调整相机参数:

use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup)
        .add_system(zoom_in)
        .run();
}

fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>) {
    // 3D相机配置,调整视场角和裁剪面确保能看到物体
    commands.spawn_bundle(Camera3dBundle {
        transform: Transform::from_xyz(0., 0., 100.).looking_at(Vec3::ZERO, Vec3::Y),
        projection: PerspectiveProjection {
            fov: 0.5, // 缩小视场角,避免物体过快消失
            near: 0.1,
            far: 1000.0,
            ..Default::default()
        },
        ..Default::default()
    });

    // 使用Mesh2dBundle替代SpriteBundle,让3D相机能识别
    commands.spawn_bundle(Mesh2dBundle {
        mesh: meshes.add(Mesh::from(shape::Quad::new(Vec2::new(50., 50.)))),
        material: materials.add(ColorMaterial::from(Color::BLUE)),
        transform: Transform::from_xyz(0., 0., 0.),
        ..Default::default()
    });
}

pub fn zoom_in(mut query: Query<&mut Transform, With<Camera>>, time: Res<Time>) {
    for mut transform in query.iter_mut() {
        transform.translation.z -= 10. * time.delta_seconds();
        transform.translation.z = transform.translation.z.max(10.); // 防止相机太近穿过物体
        warn!("Camera Z position: {}", transform.translation.z);
    }
}

内容的提问来源于stack exchange,提问作者Abb4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 03:05:25