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
相关产品推荐
相关产品推荐

