#Store a SpriteBundle in a scene in ron

40 messages · Page 1 of 1 (latest)

mint ruin
#

I want to store some SpriteBundles in a scene file and later load them with a DynamicSceneBundle. I tried to find the correct syntax by storing a SpriteBundle, but this results in an error.

Example Code:

 let mut scene_world = World::new();
    scene_world.insert_resource(world.resource::<AppTypeRegistry>().clone());
    let asset_server = world.resource::<AssetServer>();
    scene_world.spawn(
        SpriteBundle {
            texture: asset_server.load("maps/desert/desert.bmp"),
            transform: Transform::from_xyz(0.0, 0.0, -10.0),
            ..default()
        },
    );

    let type_registry = world.resource::<AppTypeRegistry>();
    let scene = DynamicScene::from_world(&scene_world);

    info!("{}", scene.serialize_ron(type_registry).unwrap());

This works for simple Components just fine.

The Error:

called `Result::unwrap()` on an `Err` value: Message("Type 'bevy_render::view::visibility::ComputedVisibilit
yFlags' did not register ReflectSerialize")

Those this mean, that I can not store Handle<T> in a ron file yet?

This seems to be a type from bevy internally that does not support Serialization.

sharp pollen
#

Unfortunately serializing a Handle is not possible at the moment (well, it might serialize but it won’t deserialize any way that’s useful)

#

Your error message seems to indicate a ReflectSerialize registration is missing from ComputedVisibilityFlags. You can manually register that yourself but Bevy should really be the one to do that. Maybe open an issue/PR for that?

mint ruin
fast sail
#

Assets v2 in 0.12 might get us slightly closer to this.

Asset Handles now use a single arc tree that represents the lifetime of the asset. This makes their implementation simpler, more efficient, and allows us to cheaply attach metadata to handles. Ex: the AssetPath of a handle is now directly accessible on the handle itself!

https://github.com/bevyengine/bevy/pull/8624

#

For the editor for my game I have a component that stores the path that I insert on the entities when saving and on load it replaces them with strong handles again.

mint ruin
#

Yeah, I will postpone this part, for the next bevy release. Thank you for the insight.

elder warren
#

Hey guys, any update on this? I'm facing the same issue and it's really holding me back

sharp pollen
#

I’ve_heard_ you can store the handle as a UUID handle, load the asset (ensuring you set its UUID to the one you stored), and then load the stored handle. It should theoretically then point to the same asset as the one you already loaded

#

Not the best solution but might be somewhat helpful

#

I know cart wants to add proper handle resolution in his BSN proposal (which would look more like @"path/to/asset")

#

Oh yeah it was actually talked about recently in this thread: #assets-dev message

elder warren
#

Okay, that could be a solution. How would I go about the current SpriteBundle, I believe it doesn't use UUID handles, so I'd have to swap it out somehow?

sharp pollen
#

SpriteBundle doesn’t dictate what method you use to generate the handle. So when you generate the handle that you pass into the bundle (or insert it without the bundle at all), just make sure you set it up with the UUID variant

elder warren
#

I just get an asset straight from asset server and pass it into the texture field. Is that the handle?
Sorry, think I may be having trouble understanding what the handle is in this context

sharp pollen
#

No worries!

#

Yeah that would be the handle managing the load. I’m not entirely sure how it all works out but I think when you somehow need to load your asset and insert it into the Assets resource using a combination of https://docs.rs/bevy/latest/bevy/asset/struct.Assets.html#method.insert and https://docs.rs/bevy/latest/bevy/asset/enum.Handle.html#method.weak_from_u128

#

There might be more details on how to actually load the asset in #assets-dev

#

I wonder if you can just load it like normal then remove and re-insert the asset 🤔

elder warren
#

I'll try what you said and get back to you later, thanks

elder warren
#

Doing .clone_weak() works and lets me serialize, however the sprite is no longer rendered in the game world

sharp pollen
#

The issue is that you need to keep around a strong handle

elder warren
#

I'm guessing because the original handle gets deleted

#

Yep

#

Should I keep them in a resource or something like that?

sharp pollen
#

Yeah that’s a pretty common pattern

elder warren
#

So there's no single Bevy idiomatic way of doing it I'm guessing

sharp pollen
#

There might be but I probably just don’t know about it lol

#

Maybe try making a new question in #1019697973933899910 . Now that Assets v2 has been out for a while, you might get some better responses

elder warren
#

sure, no worries

elder warren
#

Tried this, but somehow I'm getting the same result. It serializes fine but no sprite is rendered

#

Nevermind, it works. I wasn't requesting it properly in my system

#

This is more of a rust question rather than Bevy, but how could I go about making this work for Handle<dyn Asset>?
Ideally I'd like to be able to use an AssetPool to load all kinds of assets (images, sounds, etc) rather than having to instantiate an AssetPool resource for each type

sharp pollen
#

Hm the problem is that you’re wanting to use concrete types (T) dynamically via trait objects (dyn Trait). Which normally doesn’t work unless you can cast back to T, such as with Any::downcast

#

You might be able to use ReflectAsset to handle dynamic assets

#

It’s been a while since I’ve looked at it so I’m not 100% sure

elder warren
#

Thanks, I'll have a look into ReflectAsset

#

My current issue is trying to move the children out of the entity spawned when creating the DynamicSceneBundle. Ideally I'd want to load everything as children of the world, rather than of a new entity

#

However this creates a new entity, and I can't find a way of adding the DynamicSceneBundle directly onto the world (is world even an entity that can accept components?)