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>>) { fn added(mut commands: Commands, footsteps: Query<(Entity, &Footstep), Added<Footstep>>) {
for (entity, footstep) in &footsteps { for (entity, footstep) in &footsteps {
if let Some(audio) = &footstep.audio { 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 { commands.entity(entity).insert(Sound {
audio: audio.clone(), audio: audio.clone(),
gain: footstep.gain,
pitch,
paused: true, paused: true,
..default() ..default()
}); });
@ -72,8 +79,8 @@ fn update(
let distance = last.0 + (last.1.distance(transform)); let distance = last.0 + (last.1.distance(transform));
if distance >= footstep.step_length { if distance >= footstep.step_length {
last_step_distance.insert(entity, (0., *transform)); last_step_distance.insert(entity, (0., *transform));
if let Some(footsteps) = footsteps { let audio = if let Some(footsteps) = footsteps {
let audio = if footsteps.len() == 1 { if footsteps.len() == 1 {
Some(footsteps[0].clone()) Some(footsteps[0].clone())
} else if !footsteps.is_empty() { } else if !footsteps.is_empty() {
let mut footsteps = footsteps.clone(); let mut footsteps = footsteps.clone();
@ -88,30 +95,22 @@ fn update(
Some(audio) Some(audio)
} else { } else {
None 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 { } else {
sound.gain = footstep.gain; footstep.audio.clone()
sound.pitch = footstep.pitch.unwrap_or(1.); };
if let Some(audio) = audio {
let mut pitch = 1.;
if let Some(pitch_variation) = footstep.pitch_variation { 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; pitch += random::<f64>() * pitch_variation;
sound.pitch = pitch;
} }
sound.paused = false; commands.entity(entity).insert(Sound {
sound.restart = true; audio,
gain: footstep.gain,
pitch,
..default()
});
} }
} else if last.1 != *transform { } else if last.1 != *transform {
last_step_distance.insert(entity, (distance, *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::prelude::*;
use bevy_synthizer::{Audio, Sound}; use bevy_synthizer::{Audio, Sound};
@ -8,7 +6,7 @@ use rand::random;
use crate::{ use crate::{
core::Player, core::Player,
exploration::ExplorationFocused, exploration::ExplorationFocused,
visibility::{VisibilityChanged, Visible, VisibleEntities}, visibility::{Visible, VisibleEntities},
}; };
#[derive(Component, Clone, Debug)] #[derive(Component, Clone, Debug)]
@ -22,17 +20,12 @@ pub struct SoundIcon {
impl Default for SoundIcon { impl Default for SoundIcon {
fn default() -> Self { fn default() -> Self {
let seconds = random::<f32>() + 4.5; let seconds = random::<f32>() + 4.5;
let mut icon = Self { Self {
audio: default(), audio: default(),
gain: 1., gain: 1.,
pitch: 1., pitch: 1.,
interval: Some(Timer::from_seconds(seconds, TimerMode::Repeating)), interval: Some(Timer::from_seconds(seconds, TimerMode::Once)),
};
if let Some(ref mut interval) = icon.interval {
let seconds = Duration::from_secs_f32(seconds - 0.1);
interval.set_elapsed(seconds);
} }
icon
} }
} }
@ -82,27 +75,40 @@ fn update<S>(
}; };
if let Some(entity) = entity { if let Some(entity) = entity {
if visible.contains(&entity) { if visible.contains(&entity) {
if sound.looping { if let Some(interval) = icon.interval.as_mut() {
sound.paused = false;
} else if let Some(interval) = icon.interval.as_mut() {
interval.tick(time.delta());
if interval.finished() { if interval.finished() {
sound.paused = false;
sound.restart = true;
interval.reset(); interval.reset();
continue;
} else if interval.percent() == 0. {
sound.generator = None;
} }
interval.tick(time.delta());
} }
let buffer = icon.audio.clone(); if sound.audio != icon.audio {
if sound.audio != buffer { sound.audio = icon.audio.clone();
sound.audio = buffer; }
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 { } else if !sound.paused {
sound.paused = true; 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)] #[derive(Resource, Clone)]
pub struct SoundIconPlugin<S> { pub struct SoundIconPlugin<S> {
pub states: Vec<S>, pub states: Vec<S>,
@ -196,7 +170,7 @@ where
{ {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.insert_resource(self.clone()) 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(PreUpdate, (exploration_focus_changed, update::<S>).chain())
.add_systems( .add_systems(
PostUpdate, PostUpdate,