#![allow(clippy::unnecessary_cast)] use avian3d::{math::*, prelude::*}; use bevy::{color::palettes::css::RED, pbr::NotShadowReceiver, prelude::*}; use examples_common_3d::ExampleCommonPlugin; fn main() { App::new() .add_plugins(( DefaultPlugins, ExampleCommonPlugin, PhysicsPlugins::default(), )) .insert_resource(ClearColor(Color::srgb(0.05, 0.05, 0.1))) .insert_resource(Msaa::Sample4) .add_systems(Startup, setup) .add_systems(Update, (movement, reset_colors, raycast).chain()) .run(); } /// The acceleration used for movement. #[derive(Component)] struct MovementAcceleration(Scalar); #[derive(Component)] struct RayIndicator; /// If to be ignored by raycast #[derive(Component)] struct OutOfGlass(bool); const CUBE_COLOR: Color = Color::srgba(0.2, 0.7, 0.9, 1.0); const CUBE_COLOR_GLASS: Color = Color::srgba(0.2, 0.7, 0.9, 0.5); fn setup( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, ) { let cube_mesh = meshes.add(Cuboid::default()); // Ground commands.spawn(( PbrBundle { mesh: cube_mesh.clone(), material: materials.add(Color::srgb(0.7, 0.7, 0.8)), transform: Transform::from_xyz(0.0, -2.0, 0.0).with_scale(Vec3::new(100.0, 1.0, 100.0)), ..default() }, RigidBody::Static, Collider::cuboid(1.0, 1.0, 1.0), )); let cube_size = 2.0; // Spawn cube stacks for x in -1..2 { for y in -1..2 { for z in -1..2 { let position = Vec3::new(x as f32, y as f32 + 5.0, z as f32) * (cube_size + 0.05); let material: StandardMaterial = if x == -1 { CUBE_COLOR_GLASS.into() } else { CUBE_COLOR.into() }; commands.spawn(( PbrBundle { mesh: cube_mesh.clone(), material: materials.add(material.clone()), transform: Transform::from_translation(position) .with_scale(Vec3::splat(cube_size as f32)), ..default() }, RigidBody::Dynamic, Collider::cuboid(1.0, 1.0, 1.0), MovementAcceleration(10.0), OutOfGlass(x == -1), )); } } } // raycast indicator commands.spawn(( PbrBundle { mesh: cube_mesh.clone(), material: materials.add(Color::srgb(1.0, 0.0, 0.0)), transform: Transform::from_xyz(-500.0, 2.0, 0.0) .with_scale(Vec3::new(1000.0, 0.1, 0.1)), ..default() }, RayIndicator, NotShadowReceiver, )); // Directional light commands.spawn(DirectionalLightBundle { directional_light: DirectionalLight { illuminance: 5000.0, shadows_enabled: true, ..default() }, transform: Transform::default().looking_at(Vec3::new(-1.0, -2.5, -1.5), Vec3::Y), ..default() }); // Camera commands.spawn(Camera3dBundle { transform: Transform::from_translation(Vec3::new(0.0, 12.0, 40.0)) .looking_at(Vec3::Y * 5.0, Vec3::Y), ..default() }); } fn movement( time: Res