//! Use bevy's split screen example to test viewports with this plugin. use bevy::prelude::*; use bevy_mod_picking::prelude::*; fn main() { App::new() .add_plugins(( DefaultPlugins.set(low_latency_window_plugin()), DefaultPickingPlugins, bevy_egui::EguiPlugin, )) .insert_resource(DebugPickingMode::Normal) .add_systems(Startup, setup) .add_systems(Update, set_camera_viewports) .run(); } /// set up a simple 3D scene fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { commands.spawn(( PbrBundle { mesh: meshes.add(bevy_render::mesh::PlaneMeshBuilder::from_length(5.0)), material: materials.add(Color::srgb(0.3, 0.5, 0.3)), ..default() }, PickableBundle::default(), // <- Makes the mesh pickable. )); commands.spawn(( PbrBundle { mesh: meshes.add(Cuboid::default()), material: materials.add(Color::srgb(0.8, 0.7, 0.6)), transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }, PickableBundle::default(), // <- Makes the mesh pickable. )); commands.spawn(PointLightBundle { point_light: PointLight { shadows_enabled: true, ..default() }, transform: Transform::from_xyz(4.0, 8.0, -4.0), ..default() }); // Left Camera commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(0.0, 20.0, -10.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }, LeftCamera, )); // Right Camera commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(10.0, 10., 15.0).looking_at(Vec3::ZERO, Vec3::Y), camera: Camera { // don't clear on the second camera because the first camera already cleared the window clear_color: ClearColorConfig::None, // Renders the right camera after the left camera, which has a default priority of 0 order: 1, ..default() }, ..default() }, RightCamera, )); } #[derive(Component)] struct LeftCamera; #[derive(Component)] struct RightCamera; fn set_camera_viewports( windows: Query<&Window>, mut resize_events: EventReader, mut left_camera: Query<&mut Camera, (With, Without)>, mut right_camera: Query<&mut Camera, With>, ) { // We need to dynamically resize the camera's viewports whenever the window size changes so then // each camera always takes up half the screen. A resize_event is sent when the window is first // created, allowing us to reuse this system for initial setup. for resize_event in resize_events.read() { let window = windows.get(resize_event.window).unwrap(); let mut left_camera = left_camera.single_mut(); left_camera.viewport = Some(bevy::render::camera::Viewport { physical_position: UVec2::new(0, 0), physical_size: UVec2::new( window.resolution.physical_width() / 2, window.resolution.physical_height(), ), ..default() }); let mut right_camera = right_camera.single_mut(); right_camera.viewport = Some(bevy::render::camera::Viewport { physical_position: UVec2::new(window.resolution.physical_width() / 2, 0), physical_size: UVec2::new( window.resolution.physical_width() / 2, window.resolution.physical_height(), ), ..default() }); } }