animation_events/
animation_events.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! Demonstrate how to use animation events.

use bevy::{
    color::palettes::css::{ALICE_BLUE, BLACK, CRIMSON},
    core_pipeline::bloom::Bloom,
    prelude::*,
};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_event::<MessageEvent>()
        .add_systems(Startup, setup)
        .add_systems(Update, animate_text_opacity)
        .add_observer(edit_message)
        .run();
}

#[derive(Component)]
struct MessageText;

#[derive(Event, Clone)]
struct MessageEvent {
    value: String,
    color: Color,
}

fn edit_message(
    trigger: Trigger<MessageEvent>,
    text: Single<(&mut Text2d, &mut TextColor), With<MessageText>>,
) {
    let (mut text, mut color) = text.into_inner();
    text.0 = trigger.event().value.clone();
    color.0 = trigger.event().color;
}

fn setup(
    mut commands: Commands,
    mut animations: ResMut<Assets<AnimationClip>>,
    mut graphs: ResMut<Assets<AnimationGraph>>,
) {
    // Camera
    commands.spawn((
        Camera2d,
        Camera {
            clear_color: ClearColorConfig::Custom(BLACK.into()),
            hdr: true,
            ..Default::default()
        },
        Bloom {
            intensity: 0.4,
            ..Bloom::NATURAL
        },
    ));

    // The text that will be changed by animation events.
    commands.spawn((
        MessageText,
        Text2d::default(),
        TextFont {
            font_size: 119.0,
            ..default()
        },
        TextColor(Color::NONE),
    ));

    // Create a new animation clip.
    let mut animation = AnimationClip::default();

    // This is only necessary if you want the duration of the
    // animation to be longer than the last event in the clip.
    animation.set_duration(2.0);

    // Add events at the specified time.
    animation.add_event(
        0.0,
        MessageEvent {
            value: "HELLO".into(),
            color: ALICE_BLUE.into(),
        },
    );
    animation.add_event(
        1.0,
        MessageEvent {
            value: "BYE".into(),
            color: CRIMSON.into(),
        },
    );

    // Create the animation graph.
    let (graph, animation_index) = AnimationGraph::from_clip(animations.add(animation));
    let mut player = AnimationPlayer::default();
    player.play(animation_index).repeat();

    commands.spawn((AnimationGraphHandle(graphs.add(graph)), player));
}

// Slowly fade out the text opacity.
fn animate_text_opacity(mut colors: Query<&mut TextColor>, time: Res<Time>) {
    for mut color in &mut colors {
        let a = color.0.alpha();
        color.0.set_alpha(a - time.delta_secs());
    }
}