Skip to main content

simple_picking/
simple_picking.rs

1//! A simple scene to demonstrate picking events for UI and mesh entities.
2
3use bevy::prelude::*;
4
5fn main() {
6    App::new()
7        .add_plugins((DefaultPlugins, MeshPickingPlugin))
8        .add_systems(Startup, setup_scene)
9        .run();
10}
11
12fn setup_scene(
13    mut commands: Commands,
14    mut meshes: ResMut<Assets<Mesh>>,
15    mut materials: ResMut<Assets<StandardMaterial>>,
16) {
17    commands
18        .spawn((
19            Text::new("Click Me to get a box\nDrag cubes to rotate"),
20            Node {
21                position_type: PositionType::Absolute,
22                top: percent(12),
23                left: percent(12),
24                ..default()
25            },
26        ))
27        .observe(on_click_spawn_cube)
28        .observe(|out: On<PointerOut>, mut texts: Query<&mut TextColor>| {
29            let mut text_color = texts.get_mut(out.entity).unwrap();
30            text_color.0 = Color::WHITE;
31        })
32        .observe(|over: On<PointerOver>, mut texts: Query<&mut TextColor>| {
33            let mut color = texts.get_mut(over.entity).unwrap();
34            color.0 = bevy::color::palettes::tailwind::CYAN_400.into();
35        });
36
37    // Base
38    commands.spawn((
39        Mesh3d(meshes.add(Circle::new(4.0))),
40        MeshMaterial3d(materials.add(Color::WHITE)),
41        Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
42    ));
43
44    // Light
45    commands.spawn((
46        PointLight {
47            shadow_maps_enabled: true,
48            ..default()
49        },
50        Transform::from_xyz(4.0, 8.0, 4.0),
51    ));
52
53    // Camera
54    commands.spawn((
55        Camera3d::default(),
56        Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
57    ));
58}
59
60fn on_click_spawn_cube(
61    _click: On<PointerClick>,
62    mut commands: Commands,
63    mut meshes: ResMut<Assets<Mesh>>,
64    mut materials: ResMut<Assets<StandardMaterial>>,
65    mut num: Local<usize>,
66) {
67    commands
68        .spawn((
69            Mesh3d(meshes.add(Cuboid::new(0.5, 0.5, 0.5))),
70            MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
71            Transform::from_xyz(0.0, 0.25 + 0.55 * *num as f32, 0.0),
72        ))
73        // With the MeshPickingPlugin added, you can add pointer event observers to meshes:
74        .observe(on_drag_rotate);
75    *num += 1;
76}
77
78fn on_drag_rotate(drag: On<PointerDrag>, mut transforms: Query<&mut Transform>) {
79    if let Ok(mut transform) = transforms.get_mut(drag.entity) {
80        transform.rotate_y(drag.delta.x * 0.02);
81        transform.rotate_x(drag.delta.y * 0.02);
82    }
83}