Rust资源加载插件bevy_asset_loader_derive的使用:简化Bevy游戏引擎资源管理流程

Rust资源加载插件bevy_asset_loader_derive的使用:简化Bevy游戏引擎资源管理流程

bevy_asset_loader_derive提供了AssetCollection trait的派生宏。您很可能不需要直接使用这个crate。请查看bevy_asset_loader的README和示例了解如何使用这个派生宏。

许可证

双许可协议:

  • Apache License, Version 2.0
  • MIT license

您可以任选其一。

示例使用

下面是一个完整的示例demo,展示如何使用bevy_asset_loader_derive简化资源管理:

use bevy::prelude::*;
use bevy_asset_loader::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_loading_state(
            LoadingState::new(GameState::Loading)
                .continue_to_state(GameState::Ready)
                .with_collection::<GameAssets>()
        )
        .add_state(GameState::Loading)
        .add_system_set(
            SystemSet::on_enter(GameState::Ready)
                .with_system(use_loaded_assets)
        )
        .run();
}

#[derive(AssetCollection)]
struct GameAssets {
    #[asset(path = "textures/player.png")]
    player: Handle<Image>,
    #[asset(path = "textures/enemy.png")]
    enemy: Handle<Image>,
    #[asset(path = "audio/background.ogg")]
    background_music: Handle<AudioSource>,
}

#[derive(Clone, Eq, PartialEq, Debug, Hash)]
enum GameState {
    Loading,
    Ready,
}

fn use_loaded_assets(assets: Res<GameAssets>) {
    // 在这里可以使用加载好的资源
    // 例如: assets.player, assets.enemy, assets.background_music
}

安装

在您的项目目录中运行以下Cargo命令:

cargo add bevy_asset_loader_derive

或者在您的Cargo.toml中添加以下行:

bevy_asset_loader_derive = "0.23.0"

完整示例代码

// 引入必要的模块
use bevy::prelude::*;
use bevy_asset_loader::prelude::*;

fn main() {
    // 创建Bevy应用
    App::new()
        // 添加默认插件集
        .add_plugins(DefaultPlugins)
        // 设置加载状态
        .add_loading_state(
            LoadingState::new(GameState::Loading)
                // 加载完成后自动切换到Ready状态
                .continue_to_state(GameState::Ready)
                // 加载GameAssets集合
                .with_collection::<GameAssets>()
        )
        // 添加游戏状态
        .add_state(GameState::Loading)
        // 添加系统集,在进入Ready状态时执行
        .add_system_set(
            SystemSet::on_enter(GameState::Ready)
                .with_system(use_loaded_assets)
        )
        .run();
}

// 定义资源集合结构体
#[derive(AssetCollection)]
struct GameAssets {
    // 加载玩家纹理
    #[asset(path = "textures/player.png")]
    player: Handle<Image>,
    
    // 加载敌人纹理
    #[asset(path = "textures/enemy.png")]
    enemy: Handle<Image>,
    
    // 加载背景音乐
    #[asset(path = "audio/background.ogg")]
    background_music: Handle<AudioSource>,
}

// 定义游戏状态枚举
#[derive(Clone, Eq, PartialEq, Debug, Hash)]
enum GameState {
    Loading,  // 加载状态
    Ready,    // 准备就绪状态
}

// 使用已加载资源的函数
fn use_loaded_assets(assets: Res<GameAssets>) {
    // 在这里可以使用加载好的资源
    // 例如: assets.player, assets.enemy, assets.background_music
}

1 回复

Rust资源加载插件bevy_asset_loader_derive的使用:简化Bevy游戏引擎资源管理流程

介绍

bevy_asset_loader_derive 是一个为 Bevy 游戏引擎设计的 Rust 过程宏插件,它通过派生宏简化了游戏资源加载和管理流程。该插件可以帮助开发者以声明式的方式定义游戏资源,自动处理资源加载状态,并减少样板代码。

主要特点

  1. 简化资源定义和加载流程
  2. 自动处理资源加载状态
  3. 类型安全的资源访问
  4. 与 Bevy 的 ECS 系统无缝集成
  5. 减少资源管理相关的样板代码

完整示例demo

下面是一个完整的游戏资源加载示例,展示了如何使用bevy_asset_loader_derive管理游戏中的多种资源:

use bevy::prelude::*;
use bevy_asset_loader::prelude::*;
use bevy_asset_loader_derive::AssetCollection;

// 定义游戏状态
#[derive(Clone, Eq, PartialEq, Debug, Hash, Default, States)]
enum GameState {
    #[default]
    Loading,
    Menu,
    Playing,
}

// 主资源集合
#[derive(AssetCollection, Resource)]
struct GameAssets {
    // 单个纹理资源
    #[asset(path = "textures/player.png")]
    player: Handle<Image>,
    
    // 音频资源
    #[asset(path = "sounds/background.ogg")]
    background_music: Handle<AudioSource>,
    
    // 字体资源
    #[asset(path = "fonts/roboto.ttf")]
    font: Handle<Font>,
    
    // 批量加载场景资源
    #[asset(collection)]
    levels: Vec<Handle<Scene>>,
    
    // 标准材质
    #[asset(standard_material)]
    #[asset(path = "textures/player.png")]
    player_material: Handle<StandardMaterial>,
}

// UI资源集合
#[derive(AssetCollection, Resource)]
struct UiAssets {
    #[asset(path = "ui/main_menu.png")]
    menu_background: Handle<Image>,
    
    #[asset(path = "ui/button.png")]
    button: Handle<Image>,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<GameState>()
        // 设置加载状态
        .add_loading_state(
            LoadingState::new(GameState::Loading)
                .continue_to_state(GameState::Menu)
                .load_collection::<GameAssets>()
                .load_collection::<UiAssets>()
        )
        // 添加系统
        .add_systems(OnEnter(GameState::Menu), setup_menu)
        .add_systems(OnEnter(GameState::Playing), setup_game)
        .run();
}

// 菜单系统
fn setup_menu(
    game_assets: Res<GameAssets>,
    ui_assets: Res<UiAssets>,
    mut commands: Commands,
) {
    // 使用加载好的资源创建UI
    commands.spawn(Camera2dBundle::default());
    
    // 示例:使用UI资源创建按钮
    commands.spawn(SpriteBundle {
        texture: ui_assets.button.clone(),
        ..default()
    });
    
    // 示例:播放背景音乐
    commands.spawn(AudioBundle {
        source: game_assets.background_music.clone(),
        settings: PlaybackSettings::LOOP,
    });
}

// 游戏系统
fn setup_game(
    game_assets: Res<GameAssets>,
    mut commands: Commands,
) {
    // 示例:生成玩家实体
    commands.spawn(SpriteBundle {
        texture: game_assets.player.clone(),
        ..default()
    });
    
    // 示例:加载第一关
    if let Some(level) = game_assets.levels.first() {
        commands.spawn(SceneBundle {
            scene: level.clone(),
            ..default()
        });
    }
}

项目结构建议

为使上述代码正常工作,建议的项目资源目录结构如下:

assets/
├── textures/
│   ├── player.png
│   └── ...
├── sounds/
│   ├── background.ogg
│   └── ...
├── fonts/
│   ├── roboto.ttf
│   └── ...
├── scenes/
│   ├── level1.scn
│   ├── level2.scn
│   └── ...
└── ui/
    ├── main_menu.png
    ├── button.png
    └── ...

总结

这个完整示例展示了如何使用bevy_asset_loader_derive

  1. 定义多个资源集合
  2. 使用状态管理控制加载流程
  3. 批量加载同类型资源
  4. 加载标准材质
  5. 在游戏不同状态下使用加载好的资源

通过这种方式,你可以将资源管理代码与游戏逻辑分离,使代码更加清晰和易于维护。

回到顶部