- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 189
Closed
Description
Hi, I'm trying to make the camera follow a physics object using this system:
pub fn camera_follow_player(
    mut camera_query: Query<&mut Transform, With<MainCamera>>,
    player_query: Query<&Transform, (With<Player>, Changed<Transform>, Without<MainCamera>)>,
) {
    if let Ok(player_transform) = player_query.get_single() {
        let mut camera_transform = camera_query.single_mut();
        camera_transform.translation.x = player_transform.translation.x;
        camera_transform.translation.y = player_transform.translation.y;
    }
}which is added to the application using:
.add_systems(PostUpdate, camera_follow_player)but I end up getting jitters. What's the proper way to solve this?
(it's even worse in the actual game that I'm working on)
And the minimal reproduction code:
use bevy::prelude::*;
use bevy::sprite::MaterialMesh2dBundle;
use bevy_xpbd_2d::{math::*, prelude::*};
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(Gravity::ZERO)
        .add_plugins(PhysicsPlugins::default())
        .add_systems(Startup, setup)
        .add_systems(PostUpdate, camera_follow_player)
        .run()
}
#[derive(Component)]
pub struct Player;
#[derive(Component)]
pub struct MainCamera;
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    commands.spawn((MainCamera, Camera2dBundle::default()));
    commands.spawn((
        Player,
        RigidBody::Dynamic,
        Collider::ball(30.00),
        Position(Vector::new(0.00, 0.00)),
        LinearVelocity(Vector::new(80.00, 0.00)),
        MaterialMesh2dBundle {
            mesh: meshes.add(shape::Circle::new(30.00).into()).into(),
            material: materials.add(ColorMaterial::from(Color::BLACK)),
            transform: Transform::from_translation(Vec3::new(0.00, 0.00, 2.00)),
            ..default()
        },
    ));
    const MAP_SIZE: u8 = 50;
    const GRID_SPACING: f32 = 50.00;
    const GRID_WIDTH: f32 = 2.00;
    // Spawn horizontal lines.
    for i in 0..=MAP_SIZE {
        commands.spawn((
            Name::new(format!("Horizontal Line {}", i + 1)),
            SpriteBundle {
                transform: Transform::from_translation(Vec3::new(
                    0.0,
                    (((MAP_SIZE as f32) / 2.0) - (i as f32)) * GRID_SPACING,
                    0.0,
                )),
                sprite: Sprite {
                    color: Color::rgb(0.27, 0.27, 0.27),
                    custom_size: Some(Vec2::new(MAP_SIZE as f32 * GRID_SPACING, GRID_WIDTH)),
                    ..default()
                },
                ..default()
            },
        ));
    }
    // Spawn vertical lines.
    for i in 0..=MAP_SIZE {
        commands.spawn((
            Name::new(format!("Vertical Line {}", i + 1)),
            SpriteBundle {
                transform: Transform::from_translation(Vec3::new(
                    ((i as f32) - ((MAP_SIZE as f32) / 2.0)) * GRID_SPACING,
                    0.0,
                    0.0,
                )),
                sprite: Sprite {
                    color: Color::rgb(0.27, 0.27, 0.27),
                    custom_size: Some(Vec2::new(GRID_WIDTH, MAP_SIZE as f32 * GRID_SPACING)),
                    ..default()
                },
                ..default()
            },
        ));
    }
}
pub fn camera_follow_player(
    mut camera_query: Query<&mut Transform, With<MainCamera>>,
    player_query: Query<&Transform, (With<Player>, Changed<Transform>, Without<MainCamera>)>,
) {
    if let Ok(player_transform) = player_query.get_single() {
        let mut camera_transform = camera_query.single_mut();
        camera_transform.translation.x = player_transform.translation.x;
        camera_transform.translation.y = player_transform.translation.y;
    }
}Metadata
Metadata
Assignees
Labels
No labels
