5个版本
0.2.2 | 2023年2月8日 |
---|---|
0.2.1 | 2023年1月30日 |
0.2.0 | 2023年1月19日 |
0.1.1 | 2023年1月18日 |
0.1.0 | 2022年12月23日 |
#1814 in 游戏开发
26 每月下载量
29KB
254 行
☢️ Bevy Atomic Save
Bevy的原子保存/加载系统。
特性
概述
使用最新的Bevy版本,可以将世界的状态保存到DynamicScene(见示例)。虽然这种方法对场景管理和编辑很有用,但将相同的方法用于保存和加载游戏状态并不实用。
在大多数典型情况下,游戏只需保存世界的一小部分,以便可以从磁盘恢复其状态。游戏的可视和美学元素,如UI、模型、精灵、相机或逻辑系统,通常在游戏启动时初始化,因此不需要序列化。
此crate通过提供标记需要保存和加载的实体的框架以及将实体保存到/从磁盘的功能来解决这个问题。
使用方法
保存
- 确保将
SavePlugin
添加到您的App
中。
use bevy_atomic_save::SavePlugin;
...
app.add_plugin(SavePlugin);
- 使用
Save
组件标记任何需要保存的实体。这可以是Bundle
,也可以像普通组件一样插入。标记为保存的实体应具有派生自Reflect
的组件。任何未派生自Reflect
的组件都不会被保存。
use bevy::prelude::*;
use bevy_atomic_save::Save;
#[derive(Bundle)]
struct PlayerBundle {
/* ... Serializable Player Data ... */
save: Save,
}
- 使用
SaveWorld
通过&mut World
或&mut Commands
将世界保存到磁盘。
use bevy::prelude::*;
use bevy_atomic_save::SaveWorld;
fn trigger_save(mut commands: Commands) {
commands.save("world.ron");
}
加载
- 使用
Unload
标记在加载之前需要卸载的任何实体。
use bevy::prelude::*;
use bevy_atomic_save::Unload;
#[derive(Bundle)]
struct PlayerModelBundle {
/* ... Player Transform, Mesh, Sprite, etc. ... */
unload: Unload,
}
- 使用
LoadWorld
通过一个&mut World
或&mut Commands
加载之前保存的文件。
这会启动一个加载过程,首先反序列化给定的文件,然后递归销毁所有带有Save
或Unload
组件的实体。最后,生成新的实体并开始SaveStage::PostLoad
。
use bevy::prelude::*;
use bevy_atomic_save::LoadWorld;
fn trigger_load(mut commands: Commands) {
commands.load("world.ron");
}
- 在
SaveStage::PostLoad
期间更新实体引用。
在加载过程中,不能保证保存的实体索引得到保留。这是因为当前世界中可能已经有实体占用了这些索引,而这些实体在加载之前无法被销毁。因此,任何引用实体的组件应在SaveStage::PostLoad
期间更新其引用实体。
这可以通过为任何引用实体的组件实现FromLoaded
特性,然后使用RegisterLoaded
在你的app
中注册这些组件来实现。
有关如何实现此操作的具体示例,请参阅./examples/pawn.rs
。
或者,也可以通过在SaveStage::PostLoad
中添加一个系统并直接读取Loaded
资源来手动实现。
use bevy::prelude::*;
use bevy_atomic_save::{FromLoaded, RegisterLoaded};
#[derive(Component)]
struct SomeEntity(Entity);
impl FromLoaded for SomeEntity {
fn from_loaded(&mut self, loaded: &Loaded) {
self.0.from_loaded(loaded);
}
}
...
app.register_loaded::<SomeEntity>();
注意
资源
目前,Bevy 中的 DynamicScene
不会保存 Resource
项。为了保存/加载资源,建议将保存的资源作为带有 Save
组件的实体生成。这也让你可以精确控制哪些资源应该被保存。
Bevy 组件和实体引用
Bevy 中的一些组件引用实体(例如 Parent
和 Children
),它们需要在 SaveStage::PostLoad
期间更新其引用。此crate不提供此功能。在大多数情况下,您不需要保存此类组件,因为它们通常属于可能从加载的游戏数据生成的场景实体。
世界转储
在开发过程中,可能需要检查特定帧中的原始文本格式下的世界,用于诊断目的。此crate提供了一种简单的函数来执行此操作,它使用底层的保存系统将世界状态转储到RON文件。有关详细信息,请参阅 SaveWorld::dump
。
转储和保存请求之间的唯一区别是,转储保存所有实体,而保存只保存具有 Save
组件的实体。
转储的结果不应加载,因为它可能导致实体重复。
未来计划
- 提供异步选项
依赖项
~17-32MB
~515K SLoC