You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bevy 0.10.1:如何根据应用状态播放音效?

在Bevy中根据应用状态播放音效的正确实现

问题原因

你遇到的no method named 'current' found错误,是因为Res<State<AppState>>是Bevy的资源包装类型,需要先访问内部的State实例才能调用current()方法。另外原代码还存在逻辑问题:如果将系统加入常规运行阶段,会每帧重复加载并播放音频,导致音效重叠。

正确实现方案

推荐使用Bevy的状态切换触发机制,只在进入对应状态时播放一次音效,同时缓存音频资源避免重复加载。

1. 定义音频资源缓存结构

先创建一个资源来存储预加载的音频句柄,提升性能:

pub mod music {
    use crate::state::game_state::*;
    use bevy::prelude::*;

    #[derive(Resource)]
    pub struct AudioHandles {
        pub menu_music: Handle<AudioSource>,
        pub game_music: Handle<AudioSource>,
        // 可添加其他状态对应的音效句柄
    }
}

2. 预加载音频资源

在启动时加载所有需要的音频,存入缓存:

// 承接上面的mod
pub fn load_audio_assets(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.insert_resource(AudioHandles {
        menu_music: asset_server.load("sounds/Vitality_-_Electro_Shock_Sport_Dance.ogg"),
        game_music: asset_server.load("sounds/your_game_music.ogg"), // 替换为你的游戏音乐路径
    });
}

3. 编写状态专属的音效播放系统

为每个状态单独编写播放系统,通过on_enter限定只在进入状态时执行:

// 承接上面的mod
// 进入主菜单时播放音乐
pub fn play_menu_music(audio: Res<Audio>, audio_handles: Res<AudioHandles>) {
    audio.play(audio_handles.menu_music.clone());
}

// 进入游戏时播放音乐
pub fn play_game_music(audio: Res<Audio>, audio_handles: Res<AudioHandles>) {
    audio.play(audio_handles.game_music.clone());
}

4. 注册系统

将上述系统注册到App中,绑定对应的状态触发条件:

// 承接上面的mod
pub fn register_music_systems(app: &mut App) {
    app.add_startup_system(load_audio_assets)
        .add_system(play_menu_music.run_if(on_enter(AppState::MainMenu)))
        .add_system(play_game_music.run_if(on_enter(AppState::InGame)));
    // 可继续添加Credits、GamePaused等状态的音效播放系统
}

若需在常规系统中检查状态

如果一定要在普通运行系统中实时检查状态,需先解引用Res<State<AppState>>获取内部实例,修正后的代码如下:

pub fn play_music_system(
    audio: Res<Audio>,
    game_state: Res<State<AppState>>,
    audio_handles: Res<AudioHandles>,
) {
    // 解引用Res包装器,获取State实例后调用current()
    match game_state.current() {
        AppState::MainMenu => {
            audio.play(audio_handles.menu_music.clone());
        }
        AppState::InGame => {
            audio.play(audio_handles.game_music.clone());
        }
        AppState::Credits => {}
        AppState::GamePaused => {}
        AppState::Score => {}
    }
}

⚠️ 注意:此系统若加入Update阶段会每帧执行,导致音效持续重复播放,仅在特殊场景下使用。

内容的提问来源于stack exchange,提问作者Ruben Villalvazo Manríquez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:15:32