From 654dd32fce0a4bce11f2aa13c159c85d7ac7e75b Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Mon, 18 Aug 2025 12:21:58 -0700 Subject: [PATCH] Parallax almost wraps correctly! --- examples/parallax.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/parallax.rs | 7 +++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/examples/parallax.rs b/examples/parallax.rs index f302a9e..6b95dea 100644 --- a/examples/parallax.rs +++ b/examples/parallax.rs @@ -10,6 +10,7 @@ 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(); } @@ -87,3 +88,64 @@ 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(); + 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); + 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 ad799c4..b77d344 100644 --- a/src/parallax.rs +++ b/src/parallax.rs @@ -24,13 +24,12 @@ impl Plugin for ParallaxPlugin { pub struct ParallaxDepth(pub f32); fn move_parallax_items( - mut q: Query<(&mut Transform, &ParallaxDepth), Without>, - window: Single<&Window>, - camera: Single<(&Camera, &Transform, &GlobalTransform), (With, Changed)>, + mut q: Query<(&mut Transform, &ParallaxDepth), Without>, + camera: Single<&Transform, (With, Changed)>, mut prev_camera_pos: Local, ) { // Unpack the camera data - let (cam, cam_t, cam_gt) = *camera; + let cam_t = *camera; // Calculate how far the camera moved since the last update let delta = cam_t.translation.truncate() - *prev_camera_pos;