Simplify footstep and sound icon systems.

This commit is contained in:
Nolan Darilek 2023-10-16 07:35:08 -05:00
parent eb8887e1ed
commit e381109cad
2 changed files with 51 additions and 78 deletions

View File

@ -45,8 +45,15 @@ impl Footsteps {
fn added(mut commands: Commands, footsteps: Query<(Entity, &Footstep), Added<Footstep>>) {
for (entity, footstep) in &footsteps {
if let Some(audio) = &footstep.audio {
let mut pitch = 1.;
if let Some(pitch_variation) = footstep.pitch_variation {
pitch -= pitch_variation / 2.;
pitch += random::<f64>() * pitch_variation;
}
commands.entity(entity).insert(Sound {
audio: audio.clone(),
gain: footstep.gain,
pitch,
paused: true,
..default()
});
@ -72,8 +79,8 @@ fn update(
let distance = last.0 + (last.1.distance(transform));
if distance >= footstep.step_length {
last_step_distance.insert(entity, (0., *transform));
if let Some(footsteps) = footsteps {
let audio = if footsteps.len() == 1 {
let audio = if let Some(footsteps) = footsteps {
if footsteps.len() == 1 {
Some(footsteps[0].clone())
} else if !footsteps.is_empty() {
let mut footsteps = footsteps.clone();
@ -88,30 +95,22 @@ fn update(
Some(audio)
} else {
None
};
if let Some(audio) = audio {
let mut pitch = 1.;
if let Some(pitch_variation) = footstep.pitch_variation {
pitch -= pitch_variation / 2.;
pitch += random::<f64>() * pitch_variation;
}
commands.entity(entity).insert(Sound {
audio,
gain: footstep.gain,
pitch,
..default()
});
}
} else if let Some(mut sound) = sound {
sound.gain = footstep.gain;
sound.pitch = footstep.pitch.unwrap_or(1.);
} else {
footstep.audio.clone()
};
if let Some(audio) = audio {
let mut pitch = 1.;
if let Some(pitch_variation) = footstep.pitch_variation {
let mut pitch = sound.pitch - pitch_variation / 2.;
pitch -= pitch_variation / 2.;
pitch += random::<f64>() * pitch_variation;
sound.pitch = pitch;
}
sound.paused = false;
sound.restart = true;
commands.entity(entity).insert(Sound {
audio,
gain: footstep.gain,
pitch,
..default()
});
}
} else if last.1 != *transform {
last_step_distance.insert(entity, (distance, *transform));

View File

@ -1,5 +1,3 @@
use std::{fmt::Debug, time::Duration};
use bevy::prelude::*;
use bevy_synthizer::{Audio, Sound};
@ -8,7 +6,7 @@ use rand::random;
use crate::{
core::Player,
exploration::ExplorationFocused,
visibility::{VisibilityChanged, Visible, VisibleEntities},
visibility::{Visible, VisibleEntities},
};
#[derive(Component, Clone, Debug)]
@ -22,17 +20,12 @@ pub struct SoundIcon {
impl Default for SoundIcon {
fn default() -> Self {
let seconds = random::<f32>() + 4.5;
let mut icon = Self {
Self {
audio: default(),
gain: 1.,
pitch: 1.,
interval: Some(Timer::from_seconds(seconds, TimerMode::Repeating)),
};
if let Some(ref mut interval) = icon.interval {
let seconds = Duration::from_secs_f32(seconds - 0.1);
interval.set_elapsed(seconds);
interval: Some(Timer::from_seconds(seconds, TimerMode::Once)),
}
icon
}
}
@ -82,27 +75,40 @@ fn update<S>(
};
if let Some(entity) = entity {
if visible.contains(&entity) {
if sound.looping {
sound.paused = false;
} else if let Some(interval) = icon.interval.as_mut() {
interval.tick(time.delta());
if let Some(interval) = icon.interval.as_mut() {
if interval.finished() {
sound.paused = false;
sound.restart = true;
interval.reset();
continue;
} else if interval.percent() == 0. {
sound.generator = None;
}
interval.tick(time.delta());
}
let buffer = icon.audio.clone();
if sound.audio != buffer {
sound.audio = buffer;
if sound.audio != icon.audio {
sound.audio = icon.audio.clone();
}
if sound.gain != icon.gain {
sound.gain = icon.gain;
}
if sound.pitch != icon.pitch {
sound.pitch = icon.pitch;
}
let looping = icon.interval.is_none();
if sound.looping != looping {
sound.looping = looping;
}
if sound.paused {
sound.paused = false;
sound.generator = None;
}
sound.gain = icon.gain;
sound.pitch = icon.pitch;
sound.looping = icon.interval.is_none();
} else if !sound.paused {
sound.paused = true;
sound.restart = true;
if let Some(interval) = icon.interval.as_mut() {
interval.reset();
}
}
} else {
panic!("Should not happen");
}
}
}
@ -147,38 +153,6 @@ fn exploration_focus_removed(
}
}
fn reset_timer_on_visibility_gain(
mut events: EventReader<VisibilityChanged>,
player: Query<Entity, With<Player>>,
mut icons: Query<&mut SoundIcon>,
children: Query<&Children>,
) {
for event in events.iter() {
if let VisibilityChanged::Gained { viewer, viewed } = event {
if player.get(*viewer).is_ok() {
let mut targets = vec![];
if icons.get(*viewed).is_ok() {
targets.push(viewed);
}
if let Ok(children) = children.get(*viewed) {
for child in children.iter() {
if icons.get(*child).is_ok() {
targets.push(child);
}
}
}
for icon in targets.iter_mut() {
if let Ok(mut icon) = icons.get_mut(**icon) {
if let Some(timer) = icon.interval.as_mut() {
timer.set_elapsed(timer.duration());
}
}
}
}
}
}
}
#[derive(Resource, Clone)]
pub struct SoundIconPlugin<S> {
pub states: Vec<S>,
@ -196,7 +170,7 @@ where
{
fn build(&self, app: &mut App) {
app.insert_resource(self.clone())
.add_systems(PreUpdate, (added, reset_timer_on_visibility_gain))
.add_systems(PreUpdate, added)
.add_systems(PreUpdate, (exploration_focus_changed, update::<S>).chain())
.add_systems(
PostUpdate,