From 1525cc75f9beb2daee2a2194a84c4577f686d163 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Mon, 18 Aug 2025 22:06:22 -0700 Subject: [PATCH] There is a bug with parallax and I dont know where/what it is... --- examples/parallax.rs | 93 +++++++------------------------------------- src/parallax.rs | 67 ++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/examples/parallax.rs b/examples/parallax.rs index 5ae8e3b..771b762 100644 --- a/examples/parallax.rs +++ b/examples/parallax.rs @@ -10,7 +10,6 @@ fn main() { .add_systems(Startup, spawn_background) .add_systems(Update, move_camera) .add_systems(Update, parallax_gizmos) - .add_systems(Update, wrap_parallax_items.run_if(any_component_changed::)) .run(); } @@ -21,40 +20,40 @@ fn spawn_background( ) { let mesh = Mesh2d(meshes.add(Circle::new(1.0))); commands.spawn(( - Name::new("Depth: 1"), - Transform::default().with_scale(Vec3::splat(50.0)), + Name::new("Depth: 1.1"), + Transform::default().with_translation(Vec3::new(0.0, 0.0, 0.0)).with_scale(Vec3::splat(50.0)), mesh.clone(), MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))), - ParallaxDepth(1.0), + ParallaxDepth(1.1), Visibility::Inherited, - children![(Text2d("1.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], + children![(Text2d("1.1".into()), Transform::from_xyz(0.0, 35.0, 0.0))], )); commands.spawn(( - Name::new("Depth: 2"), - Transform::default().with_scale(Vec3::splat(50.0)), + Name::new("Depth: 2.1"), + Transform::default().with_translation(Vec3::new(0.0, 0.0, -1.0)).with_scale(Vec3::splat(50.0)), mesh.clone(), MeshMaterial2d(materials.add(ColorMaterial::from_color(GREEN))), - ParallaxDepth(2.0), + ParallaxDepth(2.1), Visibility::Inherited, children![(Text2d("2.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], )); commands.spawn(( - Name::new("Depth: 4"), - Transform::default().with_scale(Vec3::splat(50.0)), + Name::new("Depth: 4.1"), + Transform::default().with_translation(Vec3::new(0.0, 0.0, -2.0)).with_scale(Vec3::splat(50.0)), mesh.clone(), MeshMaterial2d(materials.add(ColorMaterial::from_color(BLUE))), - ParallaxDepth(4.0), + ParallaxDepth(4.1), Visibility::Inherited, - children![(Text2d("4.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], + children![(Text2d("4.1".into()), Transform::from_xyz(0.0, 35.0, 0.0))], )); commands.spawn(( - Name::new("Depth: 8"), - Transform::default().with_scale(Vec3::splat(50.0)), + Name::new("Depth: 8.1"), + Transform::default().with_translation(Vec3::new(0.0, 0.0, -3.0)).with_scale(Vec3::splat(50.0)), mesh.clone(), MeshMaterial2d(materials.add(ColorMaterial::from_color(YELLOW))), - ParallaxDepth(8.0), + ParallaxDepth(8.1), Visibility::Inherited, - children![(Text2d("8.0".into()), Transform::from_xyz(0.0, 35.0, 0.0))], + children![(Text2d("8.1".into()), Transform::from_xyz(0.0, 35.0, 0.0))], )); } @@ -86,65 +85,3 @@ fn parallax_gizmos(mut gizmos: Gizmos, q: Query<&Transform, With> .outer_edges(); }); } - -fn wrap_parallax_items( - mut items: Query<(&mut Transform, &GlobalTransform, &ViewVisibility), (With, Without, Changed)>, - camera: Single<(&Camera, &GlobalTransform), With>, - window: Single<&Window>, -) { - if !items.is_empty() { - let (cam, cam_gt) = *camera; - - // get the window size in world space - let window_size_in_world_space = { - let top_left = cam.viewport_to_world_2d(cam_gt, Vec2::ZERO).unwrap(); - let bottom_right = cam.viewport_to_world_2d(cam_gt, window.size()).unwrap(); - - Vec2::abs(Vec2::new(bottom_right.x - top_left.x, bottom_right.y - top_left.y)) - }; - info!("Window size: {:?}", window_size_in_world_space); - - // for each item in the paralax items - items.iter_mut().for_each(|(mut t, gt, v)| { - if !v.get() { - info!("The item is not visible"); - - // Get the total size (window + scale) - let total_size = window_size_in_world_space + (t.scale.truncate() * 2.0); - info!("Window size: {:?} | Object size: {:?}", window_size_in_world_space, t.scale.truncate()); - info!("Total size: {:?}", total_size); - - // Double check that item is out of bounds - let bounds_check = Vec2::abs(cam_gt.translation().truncate() - gt.translation().truncate()); - let out_of_bounds = (total_size / 2.0) - bounds_check; - info!("Bounds check {:?}", bounds_check); - info!("Out of bounds: {:?}", out_of_bounds); - info!("Starting position: {:?}", t.translation); - if out_of_bounds.x < 0.0 { - info!("Object is actually out of bounds horizontally"); - // determine if should move to the left or right relative to camera - let move_right = cam_gt.translation().x > gt.translation().x; - - // move left or right - if move_right { - t.translation.x += total_size.x; - } else { - t.translation.x -= total_size.x; - } - } - if out_of_bounds.y < 0.0 { - info!("Object is actually out of bounds vertically"); - let move_up = cam_gt.translation().y > gt.translation().y; - - // move up or down - if move_up { - t.translation.y += total_size.y; - } else { - t.translation.y -= total_size.y; - } - } - info!("Moved to {:?}", t.translation); - } - }); - } -} diff --git a/src/parallax.rs b/src/parallax.rs index b77d344..1ff4905 100644 --- a/src/parallax.rs +++ b/src/parallax.rs @@ -6,7 +6,10 @@ impl Plugin for ParallaxPlugin { fn build(&self, app: &mut App) { app.add_systems( Update, - move_parallax_items.run_if(any_component_changed::), + ( + move_parallax_items.run_if(any_component_changed::), + wrap_parallax_items.run_if(any_component_changed::), + ) ); } } @@ -49,3 +52,65 @@ fn move_parallax_items( *prev_camera_pos = cam_t.translation.truncate(); } + +fn wrap_parallax_items( + mut items: Query<(&mut Transform, &GlobalTransform, &ViewVisibility), (With, Without, Changed)>, + camera: Single<(&Camera, &GlobalTransform), With>, + window: Single<&Window>, +) { + if !items.is_empty() { + let (cam, cam_gt) = *camera; + + // get the window size in world space + let window_size_in_world_space = { + let top_left = cam.viewport_to_world_2d(cam_gt, Vec2::ZERO).unwrap(); + let bottom_right = cam.viewport_to_world_2d(cam_gt, window.size()).unwrap(); + + Vec2::abs(Vec2::new(bottom_right.x - top_left.x, bottom_right.y - top_left.y)) + }; + debug!("Window size: {:?}", window_size_in_world_space); + + // for each item in the paralax items + items.iter_mut().for_each(|(mut t, gt, v)| { + if !v.get() { + debug!("The item is not visible"); + + // Get the total size (window + scale) + let total_size = window_size_in_world_space + (t.scale.truncate() * 2.0); + debug!("Window size: {:?} | Object size: {:?}", window_size_in_world_space, t.scale.truncate()); + debug!("Total size: {:?}", total_size); + + // Double check that item is out of bounds + let bounds_check = Vec2::abs(cam_gt.translation().truncate() - gt.translation().truncate()); + let out_of_bounds = (total_size / 2.0) - bounds_check; + debug!("Bounds check {:?}", bounds_check); + debug!("Out of bounds: {:?}", out_of_bounds); + debug!("Starting position: {:?}", t.translation); + if out_of_bounds.x < 0.0 { + debug!("Object is actually out of bounds horizontally"); + // determine if should move to the left or right relative to camera + let move_right = cam_gt.translation().x > gt.translation().x; + + // move left or right + if move_right { + t.translation.x += total_size.x; + } else { + t.translation.x -= total_size.x; + } + } + if out_of_bounds.y < 0.0 { + debug!("Object is actually out of bounds vertically"); + let move_up = cam_gt.translation().y > gt.translation().y; + + // move up or down + if move_up { + t.translation.y += total_size.y; + } else { + t.translation.y -= total_size.y; + } + } + debug!("Moved to {:?}", t.translation); + } + }); + } +}