generated from 2ndbeam/bevy-template
127 lines
3 KiB
Rust
127 lines
3 KiB
Rust
use bevy::prelude::*;
|
|
use bevy_collision_plugin::{Collider, CollisionEvent, CollisionPlugin, CollisionShape};
|
|
|
|
const CHECKED_GROUPS: usize = 1 << 0 | 1 << 1;
|
|
|
|
#[derive(Component)]
|
|
struct MovingCollider;
|
|
|
|
fn moving_collider_bundle() -> impl Bundle {
|
|
(
|
|
Collider {
|
|
shapes: vec![
|
|
CollisionShape::new_aabb(Vec2::new(0., 0.), Vec2::new(10., 10.)),
|
|
CollisionShape::new_circle(Vec2::new(0., 15.), 5.),
|
|
],
|
|
mask: 0,
|
|
check_mask: CHECKED_GROUPS,
|
|
},
|
|
Transform::from_translation(Vec3::new(0., 0., 0.)),
|
|
MovingCollider,
|
|
)
|
|
}
|
|
|
|
fn zerogroup_collider_bundle() -> impl Bundle {
|
|
(
|
|
Collider {
|
|
shapes: vec![
|
|
CollisionShape::new_aabb(Vec2::new(0., 0.), Vec2::new(10., 10.)),
|
|
],
|
|
mask: 1 << 0,
|
|
check_mask: 0,
|
|
},
|
|
Transform::from_translation(Vec3::new(53., 5., 0.)),
|
|
)
|
|
}
|
|
|
|
fn firstgroup_collider_bundle() -> impl Bundle {
|
|
(
|
|
Collider {
|
|
shapes: vec![
|
|
CollisionShape::new_circle(Vec2::new(0., 0.), 5.),
|
|
],
|
|
mask: 1 << 1,
|
|
check_mask: 0,
|
|
},
|
|
Transform::from_translation(Vec3::new(53., 18., 0.)),
|
|
)
|
|
}
|
|
|
|
fn move_collider(
|
|
query: Query<&mut Transform, With<MovingCollider>>,
|
|
) {
|
|
for mut transform in query {
|
|
transform.translation.x += 50.;
|
|
}
|
|
}
|
|
|
|
fn setup(
|
|
mut commands: Commands,
|
|
) {
|
|
commands.spawn(moving_collider_bundle());
|
|
}
|
|
|
|
fn configured_app() -> App {
|
|
let mut app = App::new();
|
|
|
|
app.add_plugins(CollisionPlugin)
|
|
.add_systems(Startup, setup)
|
|
.add_systems(Update, move_collider);
|
|
|
|
app
|
|
}
|
|
|
|
#[test]
|
|
fn collider_shapes_update_properly() {
|
|
let mut app = configured_app();
|
|
|
|
app.update();
|
|
|
|
let mut query = app.world_mut().query::<&Collider>();
|
|
for collider in query.iter(app.world()) {
|
|
let aabb_offset = collider.shapes[0].current_offset();
|
|
let circle_offset = collider.shapes[1].current_offset();
|
|
|
|
let expected_aabb = Vec2::new(50., 0.);
|
|
let expected_circle = Vec2::new(50., 15.);
|
|
|
|
assert_eq!(aabb_offset, expected_aabb);
|
|
assert_eq!(circle_offset, expected_circle);
|
|
}
|
|
}
|
|
|
|
#[derive(Resource)]
|
|
struct CollisionList(Vec<Entity>);
|
|
|
|
fn setup_others(
|
|
mut commands: Commands,
|
|
) {
|
|
commands.spawn(zerogroup_collider_bundle());
|
|
commands.spawn(firstgroup_collider_bundle());
|
|
}
|
|
|
|
fn on_collision_event(
|
|
event: On<CollisionEvent>,
|
|
mut res: ResMut<CollisionList>,
|
|
) {
|
|
if !res.0.contains(&event.detected) {
|
|
res.0.push(event.detected);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn collider_detects_different_groups() {
|
|
let mut app = configured_app();
|
|
|
|
app.insert_resource(CollisionList(vec![]))
|
|
.add_systems(Startup, setup_others)
|
|
.add_observer(on_collision_event);
|
|
|
|
app.update();
|
|
|
|
let collisions = app.world().get_resource::<CollisionList>().unwrap();
|
|
let got_collisions = collisions.0.len();
|
|
let expected = 2;
|
|
|
|
assert_eq!(got_collisions, expected);
|
|
}
|