Support Warning
WebGPU is currently only supported on Chrome starting with version 113, and only on desktop. If they don't work on your configuration, you can check the WebGL2 examples
here.
Support for WebGPU in Bevy hasn't been released yet, this example has been compiled using the main branch.
use std::f32::consts::PI;
use bevy::prelude::*;
#[derive(Component)]
struct CubeState {
start_pos: Vec3,
move_speed: f32,
turn_speed: f32,
}
#[derive(Component)]
struct Center {
max_size: f32,
min_size: f32,
scale_factor: f32,
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(
Update,
(
move_cube,
rotate_cube,
scale_down_sphere_proportional_to_cube_travel_distance,
),
)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 3.0,
subdivisions: 32,
})
.unwrap(),
),
material: materials.add(Color::YELLOW.into()),
transform: Transform::from_translation(Vec3::ZERO),
..default()
},
Center {
max_size: 1.0,
min_size: 0.1,
scale_factor: 0.05,
},
));
let cube_spawn =
Transform::from_translation(Vec3::Z * -10.0).with_rotation(Quat::from_rotation_y(PI / 2.));
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::WHITE.into()),
transform: cube_spawn,
..default()
},
CubeState {
start_pos: cube_spawn.translation,
move_speed: 2.0,
turn_speed: 0.2,
},
));
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 10.0, 20.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
commands.spawn(PointLightBundle {
transform: Transform::from_translation(Vec3::ONE * 3.0),
..default()
});
}
fn move_cube(mut cubes: Query<(&mut Transform, &mut CubeState)>, timer: Res<Time>) {
for (mut transform, cube) in &mut cubes {
let forward = transform.forward();
transform.translation += forward * cube.move_speed * timer.delta_seconds();
}
}
fn rotate_cube(
mut cubes: Query<(&mut Transform, &mut CubeState), Without<Center>>,
center_spheres: Query<&Transform, With<Center>>,
timer: Res<Time>,
) {
let mut center: Vec3 = Vec3::ZERO;
for sphere in ¢er_spheres {
center += sphere.translation;
}
for (mut transform, cube) in &mut cubes {
let look_at_sphere = transform.looking_at(center, transform.local_y());
let incremental_turn_weight = cube.turn_speed * timer.delta_seconds();
let old_rotation = transform.rotation;
transform.rotation = old_rotation.lerp(look_at_sphere.rotation, incremental_turn_weight);
}
}
fn scale_down_sphere_proportional_to_cube_travel_distance(
cubes: Query<(&Transform, &CubeState), Without<Center>>,
mut centers: Query<(&mut Transform, &Center)>,
) {
let mut distances = 0.0;
for (cube_transform, cube_state) in &cubes {
distances += (cube_state.start_pos - cube_transform.translation).length();
}
for (mut transform, center) in &mut centers {
let mut new_size: f32 = center.max_size - center.scale_factor * distances;
new_size = new_size.max(center.min_size);
transform.scale = Vec3::splat(new_size);
}
}