7个版本 (4个重大更新)

0.5.0 2024年7月18日
0.4.1 2024年3月18日
0.3.0 2024年3月4日
0.2.1 2024年2月7日
0.1.0 2024年1月10日

#589 in 游戏开发

Download history 4/week @ 2024-05-29 7/week @ 2024-06-05 1/week @ 2024-06-12 1/week @ 2024-07-03 135/week @ 2024-07-17 18/week @ 2024-07-24 44/week @ 2024-07-31

每月下载量197
用于hammerspace

MIT/Apache

87KB
1.5K SLoC

Crates.io Docs License Bevy tracking

bevy_gltf_save_load (已被Blenvy取代)

bevy_gltf_save_load已被弃用,并推荐使用其继任者Blenvy,它是Blenvy项目的一部分。将不再为Bevy的bevy_gltf_save_load进行进一步的开发或维护。有关背景信息,请参阅#194

基于bevy_gltf_blueprints构建,此crate添加了为Bevy轻松保存和加载游戏世界的功能。

  • 利用蓝图和动态实体与静态实体的分离
    • 动态实体:在您的应用程序/游戏生命周期中可以改变的实体
    • 静态实体:不会改变的实体(通常,是您关卡/环境的一部分)
  • 并允许允许
    • 一个简单的保存/加载工作流程,得益于上述
    • 指定要保存或排除的实体
    • 指定要保存或排除的组件
    • 指定要保存或排除的资源
    • 较小的保存文件(只保存部分实体)

特别适用于使用Blender作为Bevy游戏引擎的编辑器,并结合Blender插件,该插件为您做了很多工作(包括为您的静态和动态资产生成单独的gltf文件)

一点提示

  • 非常具有个人观点!
  • 仍处于早期阶段,功能尚未完全完成
  • 有趣的事实:由于静态关卡结构是单独存储的,您可以更改关卡布局并仍然重新加载现有的保存文件

用法

以下是一个最小化用法示例

# Cargo.toml
[dependencies]
bevy="0.14"
bevy_gltf_save_load = "0.5"
bevy_gltf_blueprints = "0.11" // also needed
use bevy::prelude::*;
use bevy_gltf_save_load::*;

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            SaveLoadPlugin::default()
        ))
        .run();
}



// add a system to trigger saving
pub fn request_save(
    mut save_requests: EventWriter<SaveRequest>,
    keycode: Res<Input<KeyCode>>,
)
{
    if keycode.just_pressed(KeyCode::S) {
        save_requests.send(SaveRequest {
            path: "save.scn.ron".into(),
        })
    }
}

// add a system to trigger loading
pub fn request_load(
    mut load_requests: EventWriter<LoadRequest>,
    keycode: Res<Input<KeyCode>>,
)
{
    if keycode.just_pressed(KeyCode::L) {
        save_requests.send(LoadRequest {
            path: "save.scn.ron".into(),
        })
    }
}

// setting up your world
// on initial setup, the static entities & the dynamic entities are kept seperate for clarity & loaded as blueprints from 2 seperate files
pub fn setup_game(
    mut commands: Commands,
    mut next_game_state: ResMut<NextState<GameState>>,
) {
    info!("setting up game world");
    // here we actually spawn our game world/level
    let world_root = commands
        .spawn((
            Name::from("world"),
            GameWorldTag,
            InAppRunning,
            TransformBundle::default(),
            InheritedVisibility::default(),
        ))
        .id();

    // and we fill it with static entities
    let static_data = commands
        .spawn((
            Name::from("static"),
            BluePrintBundle {
                blueprint: BlueprintName("World".to_string()),
                ..Default::default()
            },
            StaticEntitiesRoot,
            Library("models".into())
        ))
        .id();

    // and we fill it with dynamic entities
    let dynamic_data = commands
        .spawn((
            Name::from("dynamic"),
            BluePrintBundle {
                blueprint: BlueprintName("World_dynamic".to_string()),
                ..Default::default()
            },
            DynamicEntitiesRoot,
            NoInBlueprint,
            Library("models".into())
        ))
        .id();
    commands.entity(world_root).add_child(static_data);
    commands.entity(world_root).add_child(dynamic_data);

    next_game_state.set(GameState::InGame)
}


请查看示例以获得更多清晰度

安装

将以下内容添加到您的[dependencies]部分中的Cargo.toml

bevy_gltf_save_load = "0.3"
bevy_gltf_blueprints = "0.10" // also needed, as bevy_gltf_save_load does not re-export it at this time

或者使用cargo add

cargo add bevy_gltf_save_load

设置

use bevy::prelude::*;
use bevy_gltf_save_load::*;

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins
            SaveLoadPlugin::default()
        ))
        .run();
}

您可能需要配置设置(否则,保存的内容不多)

use bevy::prelude::*;
use bevy_gltf_save_load::*;

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            SaveLoadPlugin {
                save_path: "scenes".into(), // where do we save files to (under assets for now) defaults to "scenes"
                component_filter: SceneFilter::Allowlist(HashSet::from([ // this is using Bevy's build in SceneFilter, you can compose what components you want to allow/deny
                    TypeId::of::<Name>(),
                    TypeId::of::<Transform>(),
                    TypeId::of::<Velocity>(),
                    // and any other commponent you want to include/exclude
                ])),
                resource_filter: SceneFilter::deny_all(), // same logic as above, but for resources : also be careful & remember to register your resources !
                ..Default::default()
            },
            // you need to configure the blueprints plugin as well (might be pre_configured in the future, but for now you need to do it manually)
            BlueprintsPlugin {
                library_folder: "models/library".into(),
                format: GltfFormat::GLB,
                aabbs: true,
                ..Default::default()
            },
        ))
        .run();
}

如何确保您的实体将被保存

  • 只有具有动态组件的实体将被保存!(该组件作为crate的一部分提供)
  • 您可以在运行时添加该组件,或者在蓝图内将其嵌入

组件过滤器

  • 默认情况下,以下组件将被保存

    • 父组件
    • 子组件
    • 蓝图名称:bevy_gltf_blueprints的一部分,在底层使用
    • 在此生成:bevy_gltf_blueprints的一部分,在底层使用
    • 动态:包含在此crate中,允许您将组件标记为动态,即可以保存!请使用此功能确保您的实体被保存!
  • 不能删除这些,因为它们是样板代码的一部分

  • 可以添加您想要的任何其他组件,根据需要允许它们等

  • 您可以在这里这里找到关于SceneFilter对象的更多信息

事件

  • 要触发SaveRequest事件以触发保存
// add a system to trigger saving
pub fn request_save(
    mut save_requests: EventWriter<SaveRequest>,
    keycode: Res<Input<KeyCode>>,
)
{
    if keycode.just_pressed(KeyCode::S) {
        save_requests.send(SaveRequest {
            path: "save.scn.ron".into(),
        })
    }
}

  • 要触发LoadRequest事件以触发加载
// add a system to trigger saving
pub fn request_load(
    mut load_requests: EventWriter<LoadRequest>,
    keycode: Res<Input<KeyCode>>,
)
{
    if keycode.just_pressed(KeyCode::L) {
        save_requests.send(LoadRequest {
            path: "save.scn.ron".into(),
        })
    }
}
  • 当保存/加载完成时,您也会收到通知
    • SavingFinished用于保存
    • LoadingFinished用于加载

注意:我强烈建议您在开始/完成保存和加载时更改状态,否则事情会变得不可预测。请参阅此示例

附加说明

  • 静态关卡蓝图/gltf文件的名称和路径将被保存为保存文件的一部分,并用于动态加载正确的静态资源,这在您有多个关卡时是必要的,因此保存中包含所有重新加载保存所需的信息

SystemSet

为了方便起见,bevy_gltf_save_load提供了两个SystemSets

示例

强烈建议您更好地了解事物的工作原理!为了开始,我推荐查看

所有示例都在这里

兼容的Bevy版本

主分支与最新的Bevy版本兼容,而分支bevy_main试图跟踪Bevy的main分支(欢迎提交更新跟踪提交的PR)。

bevy_gltf_save_load版本兼容性

bevy_gltf_save_load bevy
0.5 0.14
0.4 0.13
0.1 -0.3 0.12
分支 main 0.12
分支 bevy_main

许可证

此crate及其所有代码、内容和资产均采用Apache License 2.0或MIT许可证双重授权

依赖关系

36–74MB
~1.5M SLoC