SuperAPI AI 工具集

bevy-audio-systems

编程与开发

查看项目

更新于 10-16 06:08

技能介绍

用途

本技能用于在 Bevy 0.20+ 中通过 ECS 方式处理音频播放。当需要让一段音频开始、循环、暂停或改变音量时加载本技能。其依据来源为 Bevy 0.20 的 bevy::audio 模块以及 audio_control 示例。

主要能力

  • 播放:通过 spawn AudioPlayer::new(asset_server.load(...)) 启动音频。AudioPlayer<Source> 持有 Handle<Source>,其中 Source: Asset + Decodable。若资源尚未就绪,播放会在其就绪时开始。AudioPlayer 需要配合 PlaybackSettings。
  • 设置:PlaybackSettings 配置播放的起始行为。PlaybackSettings::LOOP 与 .with_spatial(true) 出现在空间音频示例中。对 PlaybackSettings 的修改不会影响已经在播放的音频。PlaybackMode 可选 Once、Loop、Despawn 或 Remove。
  • 控制:播放开始时,Bevy 会插入 AudioSink。控制示例查询 AudioSink 并调用 pause、toggle_mute、set_volume、set_speed 和 position。SpatialAudioSink 是空间音频对应的控制类型。
  • 重播:非循环音频播放结束且 sink 被清空后,该 AudioPlayer 无法复用。需要移除音频组件后重新添加。
  • 调度:可在 Startup 中 spawn,或在拥有 Res<AssetServer> 和 Commands 的系统中 spawn。控制系统的运行位置取决于其读取 ButtonInput<KeyCode> 和 Res<Time> 的时机。

使用方式

依赖声明:

[dependencies]
bevy = "0.20"

AudioPlayer 在 handle 就绪时启动。PlaybackSettings 仅在启动时生效。AudioSink 在播放开始后插入,是实时控制入口。

播放音乐与一次性音效示例:

use bevy::audio::{AudioSinkPlayback, Volume};

fn spawn_music(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        AudioPlayer::new(asset_server.load("audio/music.ogg")),
        PlaybackSettings::LOOP.with_volume(Volume::Linear(0.6)),
    ));
}

fn spawn_oneshot(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        AudioPlayer::new(asset_server.load("audio/ui.ogg")),
        PlaybackSettings::DESPAWN,
    ));
}

fn duck_music(mut sinks: Query<&mut AudioSink>) {
    for mut sink in &mut sinks {
        sink.set_volume(Volume::Linear(0.25));
        sink.pause();
    }
}

空间化发射器需设置 with_spatial(true) 和 Transform,其实时控制使用 SpatialAudioSink:

use bevy::audio::{AudioSinkPlayback, Volume};

fn spawn_footstep(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        AudioPlayer::new(asset_server.load("audio/step.ogg")),
        PlaybackSettings::ONCE.with_spatial(true),
        Transform::from_xyz(3.0, 0.0, 1.0),
    ));
}

fn quiet_nearby(mut sinks: Query<&mut SpatialAudioSink>) {
    for mut sink in &mut sinks {
        sink.set_volume(Volume::Linear(0.5));
    }
}

已结束的非循环播放器无法复用。需移除播放器与 sink,再用同一 handle 重新插入:

use bevy::audio::AudioSinkPlayback;

fn replay_when_empty(mut commands: Commands, playing: Query<(Entity, &AudioPlayer, &AudioSink)>) {
    for (entity, player, sink) in &playing {
        if !sink.empty() {
            continue;
        }
        let handle = player.0.clone();
        commands.entity(entity).remove::<AudioPlayer>().remove::<AudioSink>();
        commands.entity(entity).insert((
            AudioPlayer::new(handle),
            PlaybackSettings::ONCE,
        ));
    }
}

适用场景

  • 需要按实体管理音频播放、循环、暂停、静音、音量与速度的游戏或应用。
  • 需要空间化音频发射器(如脚步声)的场景。
  • 需要一次性音效播放后自动从世界中移除的场景。

限制

  • 目标版本为 Bevy 0.20+。
  • 对 PlaybackSettings 的修改不会影响已在播放的音频,实时控制应使用 AudioSink。
  • 非循环音频播放结束后 AudioPlayer 不可复用,需移除并重新添加组件。
  • 本技能仅使用已文档化的 Bevy crate 与模块,不涉及第三方音频 crate、音量曲线或混音器节点。
  • 不得从两个无序系统可变查询同一组件;需用 .chain() 排序或拆分。
  • 文档 URL 不固定 /0.20.0/ 版本,永久链接保持无版本。
  • 本技能不涉及物理、导航、网络或 XR crate。

相关技能

  • 前置:bevy-master(状态归属)、bevy-asset-scenes(AssetServer 与 Handle)。
  • 互补:bevy-input-handling(控制示例使用的按键)。
  • 下游/消费者:暂无。