Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate over Bevy Query while iterating over same or similar Query?

I'm working with Bevy ECS and trying to iterate over entities in a system, but I'm encountering issues with iterating inside an iterator (for example, iterating over entities while inside another iteration).

Here's my current approach:

pub fn move_particles(
    time: Res<Time>,
    mut particles1: Query<(Entity, &mut Particle, &mut Transform)>,
    mut particles2: Query<(Entity, &mut Particle, &mut Transform), Without<Particle>>,
) {
    
    let bounds = Vec2::new(WINDOW_SIZE.x, WINDOW_SIZE.y);
    for (e, mut particle1, mut transform1) in particles1.iter_mut() {
        particle1.update();
        transform1.translation += particle1.velocity * time.delta_secs();

        if transform1.translation.x < -bounds.x || transform1.translation.x > bounds.x {
            particle1.velocity.x *= -1.0;
        }
        if transform1.translation.y < -bounds.y || transform1.translation.y > bounds.y {
            particle1.velocity.y *= -1.0;
        }
    }

    for (e1, mut particle1, mut transform1) in particles1.iter_mut() {
        for (e2, mut particle2, mut transform2) in particles2.iter_mut() {
            if PartialEq::eq(&e1, &e2){
                continue;
            }
            let distance = transform1.translation.distance(transform2.translation);
            let influence_radius = f32::min(particle1.influence_radius, particle2.influence_radius);

            if distance < influence_radius && distance > 1.0 {
                let direction = (transform2.translation - transform1.translation).normalize();
                let force = Particle::calculate_magnetic_force(particle1.color, particle2.color);
                let attraction = direction * force * time.delta_secs();

                particle1.velocity += attraction;
                particle2.velocity -= attraction;
            }
        }
    }
}

However, I'm running into an issue where Bevy is throwing errors related to borrowing conflicts:

Cannot borrow 'particles' as mutable more than once at a time

How can I fix this or properly iterate over entities inside another iteration in Bevy ECS? Should I use ParamSet, Without, or some other method to avoid conflicts when modifying entities inside multiple nested iterations?

like image 979
Michael Avatar asked Nov 17 '25 06:11

Michael


1 Answers

You can use the provided method iter_combinations_mut instead of manually creating them:

pub fn move_particles(
    time: Res<Time>,
    mut particles: Query<(Entity, &mut Particle, &mut Transform)>,
) {
    let bounds = Vec2::new(WINDOW_SIZE.x, WINDOW_SIZE.y);
    for (e, mut particle1, mut transform1) in particles.iter_mut() {
        particle1.update();
        transform1.translation += particle1.velocity * time.delta_secs();

        if transform1.translation.x < -bounds.x || transform1.translation.x > bounds.x {
            particle1.velocity.x *= -1.0;
        }
        if transform1.translation.y < -bounds.y || transform1.translation.y > bounds.y {
            particle1.velocity.y *= -1.0;
        }
    }

    for [
        (e1, mut particle1, mut transform1),
        (e2, mut particle2, mut transform2),
    ] in particles.iter_combinations_mut()
    {
        let distance = transform1.translation.distance(transform2.translation);
        let influence_radius = f32::min(particle1.influence_radius, particle2.influence_radius);

        if distance < influence_radius && distance > 1.0 {
            let direction = (transform2.translation - transform1.translation).normalize();
            let force = Particle::calculate_magnetic_force(particle1.color, particle2.color);
            let attraction = direction * force * time.delta_secs();

            particle1.velocity += attraction;
            particle2.velocity -= attraction;
        }
    }
}
like image 58
cafce25 Avatar answered Nov 18 '25 19:11

cafce25



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!