feat(Bevy): a lot of minor cleanups for alpha release

This commit is contained in:
kaosat.dev 2024-08-13 00:26:39 +02:00
parent 2031d1b8f2
commit 8c8e502f3a
18 changed files with 65 additions and 1030 deletions

22
TODO.md
View File

@ -361,3 +361,25 @@ Bevy Side:
- [x] finally deal cleanly with gltf export failures & make sure to always reset the state of the blend file - [x] finally deal cleanly with gltf export failures & make sure to always reset the state of the blend file
clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py clear && pytest -svv --blender-template ../../testing/bevy_example/art/testing_library.blend --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration_prepare.py && pytest -svv --blender-executable /home/ckaos/tools/blender/blender-4.1.0-linux-x64/blender tests/test_bevy_integration.py
------------
POST ALPHA1 RELEASE:
BEVY:
- [ ] split up "spawn from blueprint"
- [ ] cleanup very verbose messages
- [ ] fix & cleanup trigger_instance_animation_markers_events
- [ ] fix & cleanup save & load
- [ ] experiment with Bevy side for splitting out animations
- [ ] test hot reload a bit more , improve missing parts (see above)
- [ ] make a fleshed out demo
BLENDER:
- [ ] add "right click to edit blueprint"
- [ ] overall cleanup
- [ ] review wonky logic for cross file components injections
- [ ] update & fix tests
------------
BEFORE FINAL RELASE:
- [ ] cleanup & regenerate all examples assets
- [ ] cleanup & improve all docs

View File

@ -1,18 +0,0 @@
## SystemSet
the ordering of systems is very important !
For example to replace your proxy components (stand-in components when you cannot/ do not want to use real components in the gltf file) with actual ones, which should happen **AFTER** the Blueprint based spawning,
so ```blenvy``` provides a **SystemSet** for that purpose: ```GltfBlueprintsSet```
Typically , the order of systems should be
***blenvy (GltfComponentsSet::Injection)*** => ***blenvy (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn)*** => ***replace_proxies***
see https://github.com/kaosat-dev/Blenvy/tree/main/examples/blenvy/basic for how to set it up correctly

View File

@ -219,7 +219,7 @@ This way all your levels, your dynamic entities etc, are kept seperated from UI
## Registry ## Registry
Blenvy automatically exports a Json file containing of all your registered components/ types, in order to be able to create UIs that allows you to add & edit your components directly in Blender in the [Blenvy](https://github.com/kaosat-dev/Blenvy/tree/main/tools/blenvy) Blender add-on Blenvy automatically exports a Json file containing of all your registered components/ types, in order to create UIs that allows you to add & edit your components directly in Blender in the [Blenvy](https://github.com/kaosat-dev/Blenvy/tree/main/tools/blenvy) Blender add-on
- The output file will be generated in the ```Startup``` schedule whenever you run your app. - The output file will be generated in the ```Startup``` schedule whenever you run your app.
- Every time you compile & run your app, the output json file will be updated. - Every time you compile & run your app, the output json file will be updated.
@ -314,7 +314,7 @@ The main branch is compatible with the latest Bevy release, while the branch `be
Compatibility of `blenvy` versions: Compatibility of `blenvy` versions:
| `blenvy` | `bevy` | | `blenvy` | `bevy` |
| :-- | :-- | | :-- | :-- |
| `0.1` | `0.14` | | `0.1.0-alpha.1` | `0.14` |
| branch `main` | `0.14` | | branch `main` | `0.14` |
| branch `bevy_main` | `main` | | branch `bevy_main` | `main` |

View File

@ -1,362 +0,0 @@
[![Crates.io](https://img.shields.io/crates/v/bevy_gltf_blueprints)](https://crates.io/crates/bevy_gltf_blueprints)
[![Docs](https://img.shields.io/docsrs/bevy_gltf_blueprints)](https://docs.rs/bevy_gltf_blueprints/latest/bevy_gltf_blueprints/)
[![License](https://img.shields.io/crates/l/bevy_gltf_blueprints)](https://github.com/kaosat-dev/Blenvy/blob/main/crates/bevy_gltf_blueprints/License.md)
[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)
# bevy_gltf_blueprints (deprecated in favor of Blenvy)
> bevy_gltf_blueprints has been deprecated in favor of its successor [Blenvy](https://crates.io/crates/blenvy), part of the [Blenvy project](https://github.com/kaosat-dev/Blenvy). No further development or maintenance will be done for Bevy bevy_gltf_blueprints. See [#194](https://github.com/kaosat-dev/Blenvy/issues/194) for background.
Built on [bevy_gltf_components](https://crates.io/crates/bevy_gltf_components) this crate adds the ability to define Blueprints/Prefabs for [Bevy](https://bevyengine.org/) inside gltf files and spawn them in Bevy.
* Allows you to create lightweight levels, where all assets are different gltf files and loaded after the main level is loaded
* Allows you to spawn different entities from gtlf files at runtime in a clean manner, including simplified animation support !
A blueprint is a set of **overrideable** components + a hierarchy: ie
* just a Gltf file with Gltf_extras specifying components
* a component called BlueprintName
Particularly useful when using [Blender](https://www.blender.org/) as an editor for the [Bevy](https://bevyengine.org/) game engine, combined with the Blender add-ons that do a lot of the work for you
- [gltf_auto_export](https://github.com/kaosat-dev/Blenvy/tree/main/tools/gltf_auto_export)
- [bevy_components](https://github.com/kaosat-dev/Blenvy/tree/main/tools/bevy_components)
## Usage
Here's a minimal usage example:
```toml
# Cargo.toml
[dependencies]
bevy="0.14"
bevy_gltf_blueprints = { version = "0.11.0"}
```
```rust no_run
use bevy::prelude::*;
use bevy_gltf_blueprints::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(BlueprintsPlugin)
.run();
}
// not shown here: any other setup that is not specific to blueprints
fn spawn_blueprint(
mut commands: Commands,
keycode: Res<Input<KeyCode>>,
){
if keycode.just_pressed(KeyCode::S) {
let new_entity = commands.spawn((
BlueprintName("Health_Pickup".to_string()), // mandatory !!
SpawnHere, // mandatory !!
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)), // VERY important !!
// any other component you want to insert
));
}
}
```
## Installation
Add the following to your `[dependencies]` section in `Cargo.toml`:
```toml
bevy_gltf_blueprints = "0.11.0"
```
Or use `cargo add`:
```toml
cargo add bevy_gltf_blueprints
```
## Setup
```rust no_run
use bevy::prelude::*;
use bevy_gltf_blueprints::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(BlueprintsPlugin)
.run();
}
```
you may want to configure your "library"/"blueprints" settings:
```rust no_run
use bevy::prelude::*;
use bevy_gltf_blueprints::*;
fn main() {
App::new()
.add_plugins((
BlueprintsPlugin{
library_folder: "advanced/models/library".into() // replace this with your blueprints library path , relative to the assets folder,
format: GltfFormat::GLB,// optional, use either format: GltfFormat::GLB, or format: GltfFormat::GLTF, or ..Default::default() if you want to keep the default .glb extension, this sets what extensions/ gltf files will be looked for by the library
aabbs: true, // defaults to false, enable this to automatically calculate aabb for the scene/blueprint
material_library: true, // defaults to false, enable this to enable automatic injection of materials from material library files
material_library_folder: "materials".into() //defaults to "materials" the folder to look for for the material files
..Default::default()
}
))
.run();
}
```
## Spawning entities from blueprints
You can spawn entities from blueprints like this:
```rust no_run
commands.spawn((
BlueprintName("Health_Pickup".to_string()), // mandatory !!
SpawnHere, // mandatory !!
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)), // optional
// any other component you want to insert
))
```
Once spawning of the actual entity is done, the spawned Blueprint will be *gone/merged* with the contents of Blueprint !
> Important :
you can **add** or **override** components present inside your Blueprint when spawning the BluePrint itself: ie
### Adding components not specified inside the blueprint
you can just add any additional components you need when spawning :
```rust no_run
commands.spawn((
BlueprintName("Health_Pickup".to_string()),
SpawnHere,
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
// from Rapier/bevy_xpbd: this means the entity will also have a velocity component when inserted into the world
Velocity {
linvel: Vec3::new(vel_x, vel_y, vel_z),
angvel: Vec3::new(0.0, 0.0, 0.0),
},
))
```
### Overriding components specified inside the blueprint
any component you specify when spawning the Blueprint that is also specified **within** the Blueprint will **override** that component in the final spawned entity
for example
```rust no_run
commands.spawn((
BlueprintName("Health_Pickup".to_string()),
SpawnHere,
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
HealthPowerUp(20)// if this is component is also present inside the "Health_Pickup" blueprint, that one will be replaced with this component during spawning
))
```
### BluePrintBundle
There is also a ```BluePrintBundle``` for convenience , which just has
* a ```BlueprintName``` component
* a ```SpawnHere``` component
## Additional information
- When a blueprint is spawned, all its children entities (and nested children etc) also have an ```InBlueprint``` component that gets insert
- In cases where that is undesirable, you can add a ```NoInBlueprint``` component on the entity you spawn the blueprint with, and the components above will not be add
- if you want to overwrite the **path** where this crate looks for blueprints (gltf files) , you can add a ```Library``` component , and that will be used instead of the default path
ie :
```rust no_run
commands
.spawn((
Name::from("test"),
BluePrintBundle {
blueprint: BlueprintName("TestBlueprint".to_string()),
..Default::default()
},
Library("models".into()) // now the path to the blueprint above will be /assets/models/TestBlueprint.glb
))
```
- this crate also provides a special optional ```GameWorldTag``` component: this is useful when you want to keep all your spawned entities inside a root entity
You can use it in your queries to add your entities as children of this "world"
This way all your levels, your dynamic entities etc, are kept seperated from UI nodes & other entities that are not relevant to the game world
> Note: you should only have a SINGLE entity tagged with that component !
```rust no_run
commands.spawn((
SceneBundle {
scene: models
.get(game_assets.world.id())
.expect("main level should have been loaded")
.scenes[0]
.clone(),
..default()
},
bevy::prelude::Name::from("world"),
GameWorldTag, // here it is
));
```
## SystemSet
the ordering of systems is very important !
For example to replace your proxy components (stand-in components when you cannot/ do not want to use real components in the gltf file) with actual ones, which should happen **AFTER** the Blueprint based spawning,
so ```bevy_gltf_blueprints``` provides a **SystemSet** for that purpose: ```GltfBlueprintsSet```
Typically , the order of systems should be
***bevy_gltf_components (GltfComponentsSet::Injection)*** => ***bevy_gltf_blueprints (GltfBlueprintsSet::Spawn, GltfBlueprintsSet::AfterSpawn)*** => ***replace_proxies***
see an example [here](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/basic) for how to set it up correctly
## Animation
```bevy_gltf_blueprints``` provides some lightweight helpers to deal with animations stored in gltf files
* an ```Animations``` component that gets inserted into spawned (root) entities that contains a hashmap of all animations contained inside that entity/gltf file .
(this is a copy of the ```named_animations``` inside Bevy's gltf structures )
* an ```AnimationPlayerLink``` component that gets inserted into spawned (root) entities, to make it easier to trigger/ control animations than it usually is inside Bevy + Gltf files
The workflow for animations is as follows:
* create a gltf file with animations (using Blender & co) as you would normally do
* inside Bevy, use the ```bevy_gltf_blueprints``` boilerplate (see sections above), no specific setup beyond that is required
* to control the animation of an entity, you need to query for entities that have both ```AnimationPlayerLink``` and ```Animations``` components (added by ```bevy_gltf_blueprints```) AND entities with the ```AnimationPlayer``` component
For example:
```rust no_run
// example of changing animation of entities based on proximity to the player, for "fox" entities (Tag component)
pub fn animation_change_on_proximity_foxes(
players: Query<&GlobalTransform, With<Player>>,
animated_foxes: Query<(&GlobalTransform, &AnimationPlayerLink, &Animations ), With<Fox>>,
mut animation_players: Query<&mut AnimationPlayer>,
){
for player_transforms in players.iter() {
for (fox_tranforms, link, animations) in animated_foxes.iter() {
let distance = player_transforms
.translation()
.distance(fox_tranforms.translation());
let mut anim_name = "Walk";
if distance < 8.5 {
anim_name = "Run";
}
else if distance >= 8.5 && distance < 10.0{
anim_name = "Walk";
}
else if distance >= 10.0 && distance < 15.0{
anim_name = "Survey";
}
// now play the animation based on the chosen animation name
let mut animation_player = animation_players.get_mut(link.0).unwrap();
animation_player.play_with_transition(
animations.named_animations.get(anim_name).expect("animation name should be in the list").clone(),
Duration::from_secs(3)
).repeat();
}
}
}
```
see [here](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/animation) for how to set it up correctly
particularly from [here](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/animation/src/game/in_game.rs)
## Materials
You have the option of using "material libraries" to share common textures/materials between blueprints, in order to avoid asset & memory bloat:
Ie for example without this option, 56 different blueprints using the same material with a large texture would lead to the material/texture being embeded
56 times !!
you can configure this with the settings:
```rust
material_library: true // defaults to false, enable this to enable automatic injection of materials from material library files
material_library_folder: "materials".into() //defaults to "materials" the folder to look for for the material files
```
> Important! you must take care of preloading your material librairy gltf files in advance, using for example ```bevy_asset_loader```since
```bevy_gltf_blueprints``` currently does NOT take care of loading those at runtime
see an example [here](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/materials) for how to set it up correctly
Generating optimised blueprints and material libraries can be automated using the latests version of the [Blender plugin](https://github.com/kaosat-dev/Blenvy/tree/main/tools/gltf_auto_export)
## Legacy mode
Starting in version 0.7 there is a new parameter ```legacy_mode``` for backwards compatibility
To disable the legacy mode: (enabled by default)
```rust no_run
BlueprintsPlugin{legacy_mode: false}
```
You **need** to disable legacy mode if you want to use the [```bevy_components```](https://github.com/kaosat-dev/Blenvy/tree/tools_bevy_blueprints/tools/bevy_components) Blender addon + the [```bevy_registry_export crate```](https://crates.io/crates/bevy_registry_export) !
As it create custom properties that are writen in real **ron** file format instead of a simplified version (the one in the legacy mode)
> Note: the legacy mode support will be dropped in future versions, and the default behaviour will be NO legacy mode
## Examples
* [basic](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/basic)
* [xbpd](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/basic_xpbd_physics)
* [animation](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/animation)
* [materials](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/materials)
* [multiple_levels_multiple_blendfiles](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_blueprints/multiple_levels_multiple_blendfiles)
## Compatible Bevy versions
The main branch is compatible with the latest Bevy release, while the branch `bevy_main` tries to track the `main` branch of Bevy (PRs updating the tracked commit are welcome).
Compatibility of `bevy_gltf_blueprints` versions:
| `bevy_gltf_blueprints` | `bevy` |
| :-- | :-- |
| `0.11` | `0.14` |
| `0.9 - 0.10` | `0.13` |
| `0.3 - 0.8` | `0.12` |
| `0.1 - 0.2` | `0.11` |
| branch `main` | `0.13` |
| branch `bevy_main` | `main` |
## License
This crate, all its code, contents & assets is Dual-licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](./LICENSE_APACHE.md) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](./LICENSE_MIT.md) or https://opensource.org/licenses/MIT)

View File

@ -1,145 +0,0 @@
[![Crates.io](https://img.shields.io/crates/v/bevy_gltf_components)](https://crates.io/crates/bevy_gltf_components)
[![Docs](https://img.shields.io/docsrs/bevy_gltf_components)](https://docs.rs/bevy_gltf_components/latest/bevy_gltf_components/)
[![License](https://img.shields.io/crates/l/bevy_gltf_components)](https://github.com/kaosat-dev/Blenvy/blob/main/crates/bevy_gltf_components/License.md)
[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)
# bevy_gltf_components (deprecated in favor of Blenvy)
> bevy_gltf_components has been deprecated in favor of its successor [Blenvy](https://crates.io/crates/blenvy), part of the [Blenvy project](https://github.com/kaosat-dev/Blenvy). No further development or maintenance will be done for Bevy bevy_gltf_components. See [#194](https://github.com/kaosat-dev/Blenvy/issues/194) for background.
This crate allows you to define [Bevy](https://bevyengine.org/) components direclty inside gltf files and instanciate the components on the Bevy side.
## Usage
***important*** : the plugin for processing gltf files runs in ***update*** , so you cannot use the components directly if you spawn your scene from gltf in ***setup*** (the additional components will not show up)
Please see the
* [example](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_components/basic)
* or use [```bevy_asset_loader```](https://github.com/NiklasEi/bevy_asset_loader) for reliable preloading of files, as this crate does not deal with loading your assets.
* alternatively, use the [```bevy_gltf_blueprints```](https://crates.io/crates/bevy_gltf_blueprints) crate, built on this crate's features,
that allows you to directly spawn entities from gltf based blueprints.
Here's a minimal usage example:
```toml
# Cargo.toml
[dependencies]
bevy="0.14"
bevy_gltf_components = { version = "0.6"}
```
```rust no_run
//too barebones of an example to be meaningfull, please see https://github.com/kaosat-dev/Blenvy/bevy_gltf_components/examples/basic for a real example
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(ComponentsFromGltfPlugin::default())
.add_system(spawn_level)
.run();
}
fn spawn_level(
asset_server: Res<AssetServer>,
mut commands: bevy::prelude::Commands,
keycode: Res<Input<KeyCode>>,
){
if keycode.just_pressed(KeyCode::Return) {
commands.spawn(SceneBundle {
scene: asset_server.load("basic/models/level1.glb#Scene0"),
transform: Transform::from_xyz(2.0, 0.0, -5.0),
..Default::default()
});
}
}
```
## Installation
Add the following to your `[dependencies]` section in `Cargo.toml`:
```toml
bevy_gltf_components = "0.6"
```
Or use `cargo add`:
```toml
cargo add bevy_gltf_components
```
## Configuration
starting with version 0.3, this plugin is configurable
Use the default configuration:
```rust no_run
ComponentsFromGltfPlugin::default()
```
Or disable the legacy mode: (enabled by default)
```rust no_run
ComponentsFromGltfPlugin{legacy_mode: false}
```
You **need** to disable legacy mode if you want to use the [```bevy_components```](https://github.com/kaosat-dev/Blenvy/tree/main/tools/bevy_components) Blender addon + the [```bevy_registry_export crate```](https://crates.io/crates/bevy_registry_export) !
As it create custom properties that are writen in real **ron** file format
instead of a simplified version (the one in the legacy mode)
> Note: the legacy mode support will be dropped in future versions, and the default behaviour will be NO legacy mode
## SystemSet
the ordering of systems is very important !
For example to replace your proxy components (stand-in components when you cannot/ do not want to use real components in the gltf file) with actual ones,
which should happen **AFTER** the components from the gltf files have been injected,
so ```bevy_gltf_components``` provides a **SystemSet** for that purpose:```GltfComponentsSet```
Typically , the order of systems should be
***bevy_gltf_components (GltfComponentsSet::Injection)*** => ***replace_proxies***
## Additional features
- as of version 0.5 , this crate also includes automatic handling of lights in gltf files, to attempt to match Blender's eevee rendering as close as possible:
* **BlenderLightShadows** (automatically generated by the gltf_auto_export Blender add-on) allows you to toggle light's shadows on/off in Blender and have matching
behaviour in Bevy
* **BlenderBackgroundShader** aka background color is also automatically set on the Bevy side
* **BlenderShadowSettings** sets the cascade_size on the bevy side to match the one configured in Blender
If these components are present in your gltf file, they will be handled automatically by this crate, will be ignored otherwise.
## Examples
https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_components/basic
## Compatible Bevy versions
The main branch is compatible with the latest Bevy release, while the branch `bevy_main` tries to track the `main` branch of Bevy (PRs updating the tracked commit are welcome).
Compatibility of `bevy_gltf_components` versions:
| `bevy_gltf_components` | `bevy` |
| :-- | :-- |
| `0.6` | `0.14` |
| `0.5` | `0.13` |
| `0.2 - 0.4` | `0.12` |
| `0.1` | `0.11` |
| branch `main` | `0.13` |
| branch `bevy_main` | `main` |
## License
This crate, all its code, contents & assets is Dual-licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](./LICENSE_APACHE.md) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](./LICENSE_MIT.md) or https://opensource.org/licenses/MIT)

View File

@ -1,136 +0,0 @@
[![Crates.io](https://img.shields.io/crates/v/bevy_registry_export)](https://crates.io/crates/bevy_registry_export)
[![Docs](https://img.shields.io/docsrs/bevy_registry_export)](https://docs.rs/bevy_registry_export/latest/bevy_registry_export/)
[![License](https://img.shields.io/crates/l/bevy_registry_export)](https://github.com/kaosat-dev/Blenvy/blob/main/crates/bevy_registry_export/License.md)
[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)
# bevy_registry_export (deprecated in favor of Blenvy)
> bevy_registry_export has been deprecated in favor of its successor [Blenvy](https://crates.io/crates/blenvy), part of the [Blenvy project](https://github.com/kaosat-dev/Blenvy). No further development or maintenance will be done for Bevy bevy_registry_export. See [#194](https://github.com/kaosat-dev/Blenvy/issues/194) for background.
This plugin allows you to create a Json export of all your components/ registered types.
Its main use case is as a backbone for the [```bevy_components``` Blender add-on](https://github.com/kaosat-dev/Blenvy/tree/main/tools/bevy_components), that allows you to add & edit components directly in Blender, using the actual type definitions from Bevy
(and any of your custom types & components that you register in Bevy).
## Usage
Here's a minimal usage example:
```toml
# Cargo.toml
[dependencies]
bevy="0.14"
bevy_registry_export = "0.4"
```
```rust no_run
use bevy::prelude::*;
use bevy_registry_export::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
ExportRegistryPlugin::default() // will save your registry schema json file to assets/registry.json
))
.run();
}
```
take a look at the [example](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_registry_export/basic/src/core/mod.rs) for more clarity
## Installation
Add the following to your `[dependencies]` section in `Cargo.toml`:
```toml
bevy_registry_export = "0.4"
```
Or use `cargo add`:
```toml
cargo add bevy_registry_export
```
## Setup
```rust no_run
use bevy::prelude::*;
use bevy_registry_export::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins
ExportRegistryPlugin::default()
))
.run();
}
```
you can also configure the output path
```rust no_run
use bevy::prelude::*;
use bevy_registry_export::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins
ExportRegistryPlugin {
save_path: "assets/registry.json".into(),
..Default::default()
},
))
.run();
}
```
## Usage
- The output file will be generated in the ```Startup``` schedule whenever you run your app.
- Every time you compile & run your app, the output json file will be updated.
## Examples
All examples are here:
> the examples use ```bevy_gltf_blueprints``` with the **legacy_mode** set to **FALSE** as the new custom properties generated by the Blender add-on require newer/ non legacy logic.
- https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_registry_export/basic
## Compatible Bevy versions
The main branch is compatible with the latest Bevy release, while the branch `bevy_main` tries to track the `main` branch of Bevy (PRs updating the tracked commit are welcome).
Compatibility of `bevy_registry_export` versions:
| `bevy_registry_export` | `bevy` | `bevy_components (Blender add-on)` |
| :-- | :-- |:-- |
| `0.4 ` | `0.14` | `0.3` |
| `0.3 ` | `0.13` | `0.3` |
| `0.2 ` | `0.12` | `0.3` |
| `0.1 ` | `0.12` | `0.1 -0.2` |
| branch `main` | `0.12` | `0.1` |
| branch `bevy_main` | `main` | `n/a` |
## Contributors
Thanks to all the contributors helping out with this project ! Big kudos to you, contributions are always appreciated ! :)
A big shout out to [killercup](https://github.com/killercup), that did the bulk of the Bevy side code !
## License
This crate, all its code, contents & assets is Dual-licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](./LICENSE_APACHE.md) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](./LICENSE_MIT.md) or https://opensource.org/licenses/MIT)

View File

@ -1,315 +0,0 @@
[![Crates.io](https://img.shields.io/crates/v/bevy_gltf_save_load)](https://crates.io/crates/bevy_gltf_save_load)
[![Docs](https://img.shields.io/docsrs/bevy_gltf_save_load)](https://docs.rs/bevy_gltf_save_load/latest/bevy_gltf_save_load/)
[![License](https://img.shields.io/crates/l/bevy_gltf_save_load)](https://github.com/kaosat-dev/Blenvy/blob/main/crates/bevy_gltf_save_load/License.md)
[![Bevy tracking](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue)](https://github.com/bevyengine/bevy/blob/main/docs/plugins_guidelines.md#main-branch-tracking)
# bevy_gltf_save_load (deprecated in favor of Blenvy)
> bevy_gltf_save_load has been deprecated in favor of its successor [Blenvy](https://crates.io/crates/blenvy), part of the [Blenvy project](https://github.com/kaosat-dev/Blenvy). No further development or maintenance will be done for Bevy bevy_gltf_save_load. See [#194](https://github.com/kaosat-dev/Blenvy/issues/194) for background.
Built upon [bevy_gltf_blueprints](https://crates.io/crates/bevy_gltf_blueprints) this crate adds the ability to easilly **save** and **load** your game worlds for [Bevy](https://bevyengine.org/) .
* leverages blueprints & seperation between
* **dynamic** entities : entities that can change during the lifetime of your app/game
* **static** entities : entities that do NOT change (typically, a part of your levels/ environements)
* and allows allow for :
* a simple save/load workflow thanks to the above
* ability to specify **which entities** to save or to exclude
* ability to specify **which components** to save or to exclude
* ability to specify **which resources** to save or to exclude
* small(er) save files (only a portion of the entities is saved)
Particularly useful when using [Blender](https://www.blender.org/) as an editor for the [Bevy](https://bevyengine.org/) game engine, combined with the [Blender plugin](https://github.com/kaosat-dev/Blenvy/tree/main/tools/gltf_auto_export) that does a lot of the work for you (including spliting generating seperate gltf files for your static vs dynamic assets)
A bit of heads up:
* very opinionated !
* still in the early stages & not 100% feature complete
* fun fact: as the static level structure is stored seperatly, you can change your level layout & **still** reload an existing save file
## Usage
Here's a minimal usage example:
```toml
# Cargo.toml
[dependencies]
bevy="0.14"
bevy_gltf_save_load = "0.5"
bevy_gltf_blueprints = "0.11" // also needed
```
```rust no_run
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<SavingRequest>,
keycode: Res<Input<KeyCode>>,
)
{
if keycode.just_pressed(KeyCode::S) {
save_requests.send(SavingRequest {
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)
}
```
take a look at the [example](https://github.com/kaosat-dev/Blenvy/blob/main/examples/bevy_gltf_save_load/basic/src/game/mod.rs) for more clarity
## Installation
Add the following to your `[dependencies]` section in `Cargo.toml`:
```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
```
Or use `cargo add`:
```toml
cargo add bevy_gltf_save_load
```
## Setup
```rust no_run
use bevy::prelude::*;
use bevy_gltf_save_load::*;
fn main() {
App::new()
.add_plugins((
DefaultPlugins
SaveLoadPlugin::default()
))
.run();
}
```
you likely need to configure your settings (otherwise, not much will be saved)
```rust no_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();
}
```
### How to make sure your entites will be saved
- only entites that have a **Dynamic** component will be saved ! (the component is provided as part of the crate)
- you can either add that component at runtime or have it baked-in in the Blueprint
### Component Filter:
- by default only the following components are going to be saved
- **Parent**
- **Children**
- **BlueprintName** : part of bevy_gltf_blueprints, used under the hood
- **SpawnHere** :part of bevy_gltf_blueprints, used under the hood
- **Dynamic** : included in this crate, allows you to tag components as dynamic aka saveable ! Use this to make sure your entities are saved !
- you **CANNOT** remove these as they are part of the boilerplate
- you **CAN** add however many other components you want, allow them all etc as you see fit
- you can find more information about the SceneFilter object [here](https://bevyengine.org/news/bevy-0-11/#scene-filtering) and [here](https://docs.rs/bevy/latest/bevy/scene/enum.SceneFilter.html)
## Events
- to trigger **saving** use the ```SavingRequest``` event
```rust no_run
// add a system to trigger saving
pub fn request_save(
mut save_requests: EventWriter<SavingRequest>,
keycode: Res<Input<KeyCode>>,
)
{
if keycode.just_pressed(KeyCode::S) {
save_requests.send(SavingRequest {
path: "save.scn.ron".into(),
})
}
}
```
- to trigger **loading** use the ```LoadRequest``` event
```rust no_run
// 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(),
})
}
}
```
- you also notified when saving / loading is done
- ```SavingFinished``` for saving
- ```LoadingFinished``` for loading
> Note: I **highly** recomend you change states when you start/finish saving & loading, otherwise things **will** get unpredictable
Please see [the example](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_save_load/basic/src/game/mod.rs) for this.
## Additional notes
- the name + path of the **static** level blueprint/gltf file will be saved as part of the save file, and reused to dynamically
load the correct static assets, which is necessary when you have multiple levels, and thus all required information to reload a save is contained within the save
## SystemSet
For convenience ```bevy_gltf_save_load``` provides two **SystemSets**
- [```LoadingSet```](./src/lib.rs#19)
- [```SavingSet```](./src/lib.rs#24)
## Examples
Highly advised to get a better understanding of how things work !
To get started I recomend looking at
- [world setup](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_save_load/basic/src/game/in_game.rs)
- [various events & co](https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_save_load/basic/src/game/mod.rs)
All examples are here:
- https://github.com/kaosat-dev/Blenvy/tree/main/examples/bevy_gltf_save_load/basic
## Compatible Bevy versions
The main branch is compatible with the latest Bevy release, while the branch `bevy_main` tries to track the `main` branch of Bevy (PRs updating the tracked commit are welcome).
Compatibility of `bevy_gltf_save_load` versions:
| `bevy_gltf_save_load` | `bevy` |
| :-- | :-- |
| `0.5 ` | `0.14` |
| `0.4 ` | `0.13` |
| `0.1 -0.3` | `0.12` |
| branch `main` | `0.12` |
| branch `bevy_main` | `main` |
## License
This crate, all its code, contents & assets is Dual-licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](./LICENSE_APACHE.md) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](./LICENSE_MIT.md) or https://opensource.org/licenses/MIT)

View File

@ -164,6 +164,7 @@ pub fn trigger_blueprint_animation_markers_events(
} }
/// triggers events when a given animation marker is reached for INSTANCE animations /// triggers events when a given animation marker is reached for INSTANCE animations
// TODO: implement this correctly
pub fn trigger_instance_animation_markers_events( pub fn trigger_instance_animation_markers_events(
animation_infos: Query<( animation_infos: Query<(
Entity, Entity,
@ -174,21 +175,21 @@ pub fn trigger_instance_animation_markers_events(
)>, )>,
animation_players: Query<&AnimationPlayer>, animation_players: Query<&AnimationPlayer>,
animation_clips: Res<Assets<AnimationClip>>, animation_clips: Res<Assets<AnimationClip>>,
animation_graphs: Res<Assets<AnimationGraph>>, __animation_graphs: Res<Assets<AnimationGraph>>,
mut animation_marker_events: EventWriter<AnimationMarkerReached>, mut _animation_marker_events: EventWriter<AnimationMarkerReached>,
) { ) {
for (entity, markers, player_link, animations, animation_infos) in animation_infos.iter() { for (__entity, __markers, player_link, animations, __animation_infos) in animation_infos.iter() {
//let (animation_player, animation_transitions) = animation_players.get(player_link.0).unwrap(); //let (animation_player, animation_transitions) = animation_players.get(player_link.0).unwrap();
//let foo = animation_transitions.get_main_animation().unwrap(); //let foo = animation_transitions.get_main_animation().unwrap();
for (animation_name, node_index) in animations.named_indices.iter() { for (animation_name, node_index) in animations.named_indices.iter() {
let animation_player = animation_players.get(player_link.0).unwrap(); let animation_player = animation_players.get(player_link.0).unwrap();
if animation_player.animation_is_playing(*node_index) { if animation_player.animation_is_playing(*node_index) {
if let Some(animation) = animation_player.animation(*node_index) { if let Some(__animation) = animation_player.animation(*node_index) {
if let Some(animation_clip_handle) = if let Some(animation_clip_handle) =
animations.named_animations.get(animation_name) animations.named_animations.get(animation_name)
{ {
if let Some(animation_clip) = animation_clips.get(animation_clip_handle) { if let Some(__animation_clip) = animation_clips.get(animation_clip_handle) {
println!("helooo") println!("helooo")
} }
} }

View File

@ -90,7 +90,7 @@ pub(crate) struct BlueprintPreloadAssets{
#[derive(Component)] #[derive(Component)]
pub(crate) struct BlueprintMetaHandle(pub Handle<BlueprintPreloadAssets>); pub(crate) struct BlueprintMetaHandle(pub Handle<BlueprintPreloadAssets>);
/// flag component, usually added when a blueprint is loaded /// flag component, usually added when a blueprint meta file is loaded
#[derive(Component)] #[derive(Component)]
pub(crate) struct BlueprintMetaLoaded; pub(crate) struct BlueprintMetaLoaded;

View File

@ -18,7 +18,7 @@ pub(crate) fn react_to_asset_changes(
mut gltf_events: EventReader<AssetEvent<Gltf>>, // FIXME: Problem: we need to react to any asset change, not just gltf files ! mut gltf_events: EventReader<AssetEvent<Gltf>>, // FIXME: Problem: we need to react to any asset change, not just gltf files !
// mut untyped_events: EventReader<AssetEvent<LoadedUntypedAsset>>, // mut untyped_events: EventReader<AssetEvent<LoadedUntypedAsset>>,
blueprint_assets: Query<(Entity, Option<&Name>, &BlueprintInfo, Option<&Children>)>, blueprint_assets: Query<(Entity, Option<&Name>, &BlueprintInfo, Option<&Children>)>,
blueprint_children_entities: Query<&FromBlueprint>, //=> can only be used if the entites are tagged _blueprint_children_entities: Query<&FromBlueprint>, //=> can only be used if the entites are tagged
assets_to_blueprint_instances: Res<AssetToBlueprintInstancesMapper>, assets_to_blueprint_instances: Res<AssetToBlueprintInstancesMapper>,
all_parents: Query<&Parent>, all_parents: Query<&Parent>,
spawning_blueprints: Query<&BlueprintSpawning>, spawning_blueprints: Query<&BlueprintSpawning>,

View File

@ -22,7 +22,7 @@ pub(crate) use hot_reload::*;
use bevy::{prelude::*, utils::hashbrown::HashMap}; use bevy::{prelude::*, utils::hashbrown::HashMap};
use crate::{BlenvyConfig, GltfComponentsSet}; use crate::GltfComponentsSet;
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
/// set for the two stages of blueprint based spawning : /// set for the two stages of blueprint based spawning :
@ -93,7 +93,6 @@ impl Plugin for BlueprintsPlugin {
.register_type::<BlueprintInfo>() .register_type::<BlueprintInfo>()
.register_type::<MaterialInfo>() .register_type::<MaterialInfo>()
.register_type::<MaterialInfos>() .register_type::<MaterialInfos>()
.register_type::<SpawnBlueprint>() .register_type::<SpawnBlueprint>()
.register_type::<BlueprintInstanceDisabled>() .register_type::<BlueprintInstanceDisabled>()
.register_type::<HideUntilReady>() .register_type::<HideUntilReady>()
@ -111,8 +110,6 @@ impl Plugin for BlueprintsPlugin {
.register_type::<Vec<String>>() .register_type::<Vec<String>>()
.register_type::<BlueprintAssets>() .register_type::<BlueprintAssets>()
.register_type::<HashMap<String, Vec<String>>>() .register_type::<HashMap<String, Vec<String>>>()
//.init_asset::<RawGltfAsset>()
//.init_asset_loader::<RawGltfAssetLoader>()
.add_plugins(RonAssetPlugin::<BlueprintPreloadAssets>::new(&["meta.ron"]),) .add_plugins(RonAssetPlugin::<BlueprintPreloadAssets>::new(&["meta.ron"]),)
.configure_sets( .configure_sets(

View File

@ -4,11 +4,11 @@ use bevy::{
gltf::Gltf, gltf::Gltf,
prelude::*, prelude::*,
scene::SceneInstance, scene::SceneInstance,
utils::{hashbrown::HashMap, warn}, utils::hashbrown::HashMap,
}; };
use crate::{ use crate::{
AnimationInfos, AssetLoadTracker, AssetToBlueprintInstancesMapper, BlueprintAnimationInfosLink, BlueprintAnimationPlayerLink, BlueprintAnimations, BlueprintAssets, BlueprintAssetsLoadState, BlueprintAssetsLoaded, BlueprintMetaLoading, BlueprintAssetsNotLoaded, BlueprintPreloadAssets, InstanceAnimationInfosLink, InstanceAnimationPlayerLink, InstanceAnimations, WatchingForChanges AnimationInfos, AssetLoadTracker, AssetToBlueprintInstancesMapper, BlueprintAnimationInfosLink, BlueprintAnimationPlayerLink, BlueprintAnimations, BlueprintAssetsLoadState, BlueprintAssetsLoaded, BlueprintAssetsNotLoaded, BlueprintMetaLoaded, BlueprintMetaLoading, BlueprintPreloadAssets, InstanceAnimationInfosLink, InstanceAnimationPlayerLink, InstanceAnimations, WatchingForChanges
}; };
@ -46,12 +46,6 @@ pub struct SpawnBlueprint;
/// flag component marking any spawned child of blueprints /// flag component marking any spawned child of blueprints
pub struct FromBlueprint; pub struct FromBlueprint;
// TODO: move to save_load
#[derive(Component, Reflect, Debug, Default)]
#[reflect(Component)]
/// component used to mark any entity as Dynamic: aka add this to make sure your entity is going to be saved
pub struct DynamicBlueprintInstance;
#[derive(Component, Reflect, Default, Debug)] #[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)] #[reflect(Component)]
/// flag component to force adding newly spawned entity as child of game world /// flag component to force adding newly spawned entity as child of game world
@ -207,7 +201,7 @@ pub(crate) fn blueprints_check_assets_metadata_files_loading(
mut commands: Commands, mut commands: Commands,
) { ) {
for (entity, blueprint_info, mut assets_to_load) in blueprint_assets_to_load.iter_mut() { for (entity, _blueprint_info, mut assets_to_load) in blueprint_assets_to_load.iter_mut() {
let mut all_loaded = true; let mut all_loaded = true;
let mut loaded_amount = 0; let mut loaded_amount = 0;
@ -240,7 +234,7 @@ pub(crate) fn blueprints_check_assets_metadata_files_loading(
pub(super) fn blueprints_prepare_spawn( pub(super) fn blueprints_prepare_spawn(
blueprint_instances_to_spawn: Query<(Entity, &BlueprintInfo, &BlueprintMetaHandle, Option<&Name>), Added<BlueprintMetaHandle>>, blueprint_instances_to_spawn: Query<(Entity, &BlueprintInfo, &BlueprintMetaHandle), Added<BlueprintMetaHandle>>,
mut commands: Commands, mut commands: Commands,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
// for hot reload // for hot reload
@ -251,7 +245,7 @@ pub(super) fn blueprints_prepare_spawn(
blueprint_metas: Res<Assets<BlueprintPreloadAssets>>, blueprint_metas: Res<Assets<BlueprintPreloadAssets>>,
) { ) {
for (entity, blueprint_info, blueprint_meta_handle, entity_name) in blueprint_instances_to_spawn.iter() { for (entity, blueprint_info, blueprint_meta_handle) in blueprint_instances_to_spawn.iter() {
info!( info!(
"Step 2: metadata loaded: loading assets for {:?}", "Step 2: metadata loaded: loading assets for {:?}",
blueprint_info, blueprint_info,
@ -368,6 +362,7 @@ pub(super) fn blueprints_prepare_spawn(
} }
commands.entity(entity) commands.entity(entity)
.insert(BlueprintMetaLoaded)
.remove::<BlueprintMetaLoading>() .remove::<BlueprintMetaLoading>()
.remove::<BlueprintMetaHandle>(); .remove::<BlueprintMetaHandle>();
} }
@ -376,14 +371,14 @@ pub(super) fn blueprints_prepare_spawn(
/// This system tracks & updates the loading state of all blueprints assets /// This system tracks & updates the loading state of all blueprints assets
pub(crate) fn blueprints_check_assets_loading( pub(crate) fn blueprints_check_assets_loading(
mut blueprint_assets_to_load: Query< mut blueprint_assets_to_load: Query<
(Entity, &BlueprintInfo, &mut BlueprintAssetsLoadState, Option<&Name>), (Entity, &BlueprintInfo, &mut BlueprintAssetsLoadState),
With<BlueprintAssetsNotLoaded>, With<BlueprintAssetsNotLoaded>,
>, >,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
mut commands: Commands, mut commands: Commands,
mut blueprint_events: EventWriter<BlueprintEvent>, mut blueprint_events: EventWriter<BlueprintEvent>,
) { ) {
for (entity, blueprint_info, mut assets_to_load, entity_name) in blueprint_assets_to_load.iter_mut() { for (entity, blueprint_info, mut assets_to_load) in blueprint_assets_to_load.iter_mut() {
let mut all_loaded = true; let mut all_loaded = true;
let mut loaded_amount = 0; let mut loaded_amount = 0;
let total = assets_to_load.asset_infos.len(); let total = assets_to_load.asset_infos.len();
@ -433,7 +428,6 @@ pub(crate) fn blueprints_assets_loaded(
&BlueprintInfo, &BlueprintInfo,
Option<&Transform>, Option<&Transform>,
Option<&Name>, Option<&Name>,
Option<&AnimationInfos>,
), ),
( (
Added<BlueprintAssetsLoaded>, Added<BlueprintAssetsLoaded>,
@ -453,7 +447,6 @@ pub(crate) fn blueprints_assets_loaded(
blueprint_info, blueprint_info,
transform, transform,
name, name,
animation_infos,
) in spawn_placeholders.iter() ) in spawn_placeholders.iter()
{ {
/*info!( /*info!(
@ -652,7 +645,7 @@ pub(crate) fn blueprints_scenes_spawned(
use crate::CopyComponents; use crate::CopyComponents;
use std::any::TypeId; use std::any::TypeId;
use super::{BlueprintMetaHandle, BlueprintMetaLoaded}; use super::BlueprintMetaHandle;
#[derive(Component, Reflect, Debug)] #[derive(Component, Reflect, Debug)]
#[reflect(Component)] #[reflect(Component)]
@ -840,6 +833,7 @@ pub(crate) fn blueprints_finalize_instances(
info!("Step 8: Finalizing blueprint instance {:?}", name); info!("Step 8: Finalizing blueprint instance {:?}", name);
commands commands
.entity(entity) .entity(entity)
.remove::<BlueprintMetaLoaded>()
.remove::<BlueprintReadyForFinalizing>() .remove::<BlueprintReadyForFinalizing>()
.remove::<BlueprintReadyForPostProcess>() .remove::<BlueprintReadyForPostProcess>()
.remove::<BlueprintSpawning>() .remove::<BlueprintSpawning>()

View File

@ -1,4 +1,4 @@
use bevy::{prelude::*, render::primitives::Aabb, utils::HashMap}; use bevy::{render::primitives::Aabb, utils::HashMap};
use std::path::PathBuf; use std::path::PathBuf;
pub mod components; pub mod components;
@ -29,8 +29,8 @@ pub struct BlenvyConfig {
// save & load // save & load
pub(crate) save_component_filter: SceneFilter, pub(crate) save_component_filter: SceneFilter,
pub(crate) save_resource_filter: SceneFilter, pub(crate) save_resource_filter: SceneFilter,
//pub(crate) save_path: PathBuf, #[allow(dead_code)]
// save_path: PathBuf::from("saves"), pub(crate) save_path: PathBuf,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -45,6 +45,7 @@ pub struct BlenvyPlugin {
// for save & load // for save & load
pub save_component_filter: SceneFilter, pub save_component_filter: SceneFilter,
pub save_resource_filter: SceneFilter, pub save_resource_filter: SceneFilter,
pub save_path: PathBuf
} }
impl Default for BlenvyPlugin { impl Default for BlenvyPlugin {
@ -57,6 +58,7 @@ impl Default for BlenvyPlugin {
save_component_filter: SceneFilter::default(), save_component_filter: SceneFilter::default(),
save_resource_filter: SceneFilter::default(), save_resource_filter: SceneFilter::default(),
save_path: PathBuf::from("blenvy_saves") // TODO: use https://docs.rs/dirs/latest/dirs/ to default to the correct user directory
} }
} }
} }
@ -83,6 +85,7 @@ impl Plugin for BlenvyPlugin {
save_component_filter: self.save_component_filter.clone(), save_component_filter: self.save_component_filter.clone(),
save_resource_filter: self.save_resource_filter.clone(), save_resource_filter: self.save_resource_filter.clone(),
save_path: self.save_path.clone()
}); });
} }
} }

View File

@ -2,17 +2,17 @@ pub use bevy::prelude::*;
use crate::{BlueprintInfo, GameWorldTag, HideUntilReady, SpawnBlueprint}; use crate::{BlueprintInfo, GameWorldTag, HideUntilReady, SpawnBlueprint};
use super::{BlueprintWorld, Dynamic}; use super::BlueprintWorld;
pub(crate) fn spawn_from_blueprintworld( pub(crate) fn spawn_from_blueprintworld(
added_blueprint_worlds: Query<(Entity, &BlueprintWorld), Added<BlueprintWorld> >, added_blueprint_worlds: Query<(Entity, &BlueprintWorld), Added<BlueprintWorld> >,
mut commands: Commands, mut commands: Commands,
){ ){
for (entity, blueprint_world) in added_blueprint_worlds.iter(){ for (__entity, blueprint_world) in added_blueprint_worlds.iter(){
println!("added blueprintWorld {:?}", blueprint_world); println!("added blueprintWorld {:?}", blueprint_world);
// here we spawn the static part our game world/level, which is also a blueprint ! // here we spawn the static part our game world/level, which is also a blueprint !
let static_world = commands.spawn(( let __static_world = commands.spawn((
BlueprintInfo::from_path(blueprint_world.path.as_str()), // all we need is a Blueprint info... BlueprintInfo::from_path(blueprint_world.path.as_str()), // all we need is a Blueprint info...
SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now
HideUntilReady, // only reveal the level once it is ready HideUntilReady, // only reveal the level once it is ready
@ -20,7 +20,7 @@ pub(crate) fn spawn_from_blueprintworld(
)).id(); )).id();
// here we spawn the dynamic entities part of our game world/level, which is also a blueprint ! // here we spawn the dynamic entities part of our game world/level, which is also a blueprint !
let dynamic_world = commands.spawn(( let __dynamic_world = commands.spawn((
BlueprintInfo::from_path(blueprint_world.path.replace(".glb", "_dynamic.glb").replace(".gltf", "_dynamic.gltf").as_str()), // all we need is a Blueprint info... BlueprintInfo::from_path(blueprint_world.path.replace(".glb", "_dynamic.glb").replace(".gltf", "_dynamic.gltf").as_str()), // all we need is a Blueprint info...
SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now
HideUntilReady, // only reveal the level once it is ready HideUntilReady, // only reveal the level once it is ready
@ -32,6 +32,7 @@ pub(crate) fn spawn_from_blueprintworld(
} }
} }
/*
pub(crate) fn inject_dynamic_into_children( pub(crate) fn inject_dynamic_into_children(
added_dynamic: Query<Entity, Added<Dynamic> >, added_dynamic: Query<Entity, Added<Dynamic> >,
all_children: Query<&Children>, all_children: Query<&Children>,
@ -42,4 +43,4 @@ pub(crate) fn inject_dynamic_into_children(
commands.entity(child).insert(Dynamic); commands.entity(child).insert(Dynamic);
} }
} }
} }*/

View File

@ -1,8 +1,6 @@
use std::path::Path;
use bevy::prelude::*; use bevy::prelude::*;
use crate::{BlenvyConfig, BlueprintInfo, DynamicEntitiesRoot, GameWorldTag, HideUntilReady, SpawnBlueprint}; use crate::{BlueprintInfo, DynamicEntitiesRoot, GameWorldTag, HideUntilReady, SpawnBlueprint};
#[derive(Event)] #[derive(Event)]
@ -89,7 +87,7 @@ pub(crate) fn load_game(
// and we fill it with dynamic data // and we fill it with dynamic data
// let input = std::fs::read(&path)?; // let input = std::fs::read(&path)?;
let dynamic_data = commands let _dynamic_data = commands
.spawn(( .spawn((
DynamicSceneBundle { DynamicSceneBundle {
scene: asset_server.load(load_request.path.clone()), scene: asset_server.load(load_request.path.clone()),
@ -101,7 +99,7 @@ pub(crate) fn load_game(
)) ))
.id(); .id();
let static_data = commands.spawn(( let _static_data = commands.spawn((
BlueprintInfo::from_path("levels/World.glb"), // all we need is a Blueprint info... BlueprintInfo::from_path("levels/World.glb"), // all we need is a Blueprint info...
SpawnBlueprint, SpawnBlueprint,
HideUntilReady, HideUntilReady,

View File

@ -1,6 +1,3 @@
use std::path::Path;
use bevy::prelude::*;
pub mod common; pub mod common;
pub use common::*; pub use common::*;
@ -44,14 +41,13 @@ pub struct StaticEntitiesBlueprintInfo {
} }
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct BlueprintWorld{ pub struct BlueprintWorld{
pub path: String, pub path: String,
} }
impl BlueprintWorld { impl BlueprintWorld {
pub fn from_path(path: &str) -> BlueprintWorld { pub fn from_path(path: &str) -> BlueprintWorld {
let p = Path::new(&path); // let p = Path::new(&path);
return BlueprintWorld { return BlueprintWorld {
// name: p.file_stem().unwrap().to_os_string().into_string().unwrap(), // seriously ? , also unwraps !! // name: p.file_stem().unwrap().to_os_string().into_string().unwrap(), // seriously ? , also unwraps !!
path: path.into(), path: path.into(),

View File

@ -2,7 +2,6 @@ use std::fs::File;
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use bevy::render::camera::{CameraMainTextureUsages, CameraRenderGraph};
use bevy::{prelude::*, tasks::IoTaskPool}; use bevy::{prelude::*, tasks::IoTaskPool};
use bevy::prelude::World; use bevy::prelude::World;
@ -51,7 +50,7 @@ pub(crate) fn prepare_save_game(
saveables: Query<Entity, (With<Dynamic>, With<BlueprintInfo>)>, saveables: Query<Entity, (With<Dynamic>, With<BlueprintInfo>)>,
root_entities: Query<Entity, Or<(With<DynamicEntitiesRoot>, Without<Parent>)>>, // With<DynamicEntitiesRoot> root_entities: Query<Entity, Or<(With<DynamicEntitiesRoot>, Without<Parent>)>>, // With<DynamicEntitiesRoot>
dynamic_entities: Query<(Entity, &Parent, Option<&Children>), With<Dynamic>>, dynamic_entities: Query<(Entity, &Parent, Option<&Children>), With<Dynamic>>,
static_entities: Query<(Entity, &BlueprintInfo), With<StaticEntitiesRoot>>, _static_entities: Query<(Entity, &BlueprintInfo), With<StaticEntitiesRoot>>,
mut commands: Commands, mut commands: Commands,
) { ) {
@ -147,7 +146,7 @@ pub(crate) fn save_game(world: &mut World) {
.with_filter(filter.clone()) .with_filter(filter.clone())
.with_resource_filter(filter_resources.clone()); .with_resource_filter(filter_resources.clone());
let mut dyn_scene = scene_builder let dyn_scene = scene_builder
.extract_resources() .extract_resources()
.extract_entities(saveable_entities.clone().into_iter()) .extract_entities(saveable_entities.clone().into_iter())
.remove_empty_entities() .remove_empty_entities()
@ -158,7 +157,7 @@ pub(crate) fn save_game(world: &mut World) {
.with_filter(filter_root.clone()) .with_filter(filter_root.clone())
.with_resource_filter(filter_resources.clone()); .with_resource_filter(filter_resources.clone());
let mut dyn_scene_root = scene_builder_root let mut __dyn_scene_root = scene_builder_root
.extract_resources() .extract_resources()
.extract_entities( .extract_entities(
saveable_root_entities.clone().into_iter(), // .chain(static_world_markers.into_iter()), saveable_root_entities.clone().into_iter(), // .chain(static_world_markers.into_iter()),

View File

@ -1,7 +1,7 @@
use crate::{GameState, InAppRunning}; use crate::{GameState, InAppRunning};
use bevy::prelude::*; use bevy::prelude::*;
use blenvy::{ use blenvy::{
AddToGameWorld, BluePrintBundle, BlueprintInfo, DynamicBlueprintInstance, GameWorldTag, AddToGameWorld, BluePrintBundle, BlueprintInfo, Dynamic, GameWorldTag,
HideUntilReady, SpawnBlueprint, HideUntilReady, SpawnBlueprint,
}; };
@ -61,7 +61,7 @@ pub fn spawn_test(
}, // FIXME }, // FIXME
..Default::default() ..Default::default()
}, },
DynamicBlueprintInstance, Dynamic,
bevy::prelude::Name::from(format!("test{}", name_index)), bevy::prelude::Name::from(format!("test{}", name_index)),
HideUntilReady, HideUntilReady,
AddToGameWorld, AddToGameWorld,