bevy_asset_loader
bevy_asset_loader copied to clipboard
gltf scenes randomly get swapped
Since the 0.12 update it seems to be possible to spawn gltf scenes without the #Scene0
at the end of the path, using bevy_asset_loader.
However, doing this I ran into a strange issue where sometimes when I open the app the scenes get swapped.
Here A and B are two different files:
And on another run:
Reproducer can be found here: https://github.com/GitGhillie/asset_loading_mre
Does it still happen when you use the label #Scene0
?
Have you tried to reproduce this without bevy_asset_loader?
It does not, but it's quite the footgun imo
It does not, but it's quite the footgun imo
Yeah, definitely a bug. Just trying to understand where the issue might be.
Have you tried to reproduce this without bevy_asset_loader?
Haven't tried to reproduce without yet (I did try some things but I've never looked into assets before so it will take me while to come up with something that's equivalent I guess). I did try with bevy_asset_loader on bevy main (2951ddf), same issue
For example, if I try scene_handles.handle_a = asset_server.load("A.glb");
and then try to spawn it:
#[derive(Resource, Default)]
struct SceneHandles {
handle_a: Handle<Scene>,
handle_b: Handle<Scene>,
}
...
commands.spawn((
Name::from("Scene A"),
SceneBundle {
scene: scene_handles.handle_a.clone(),
transform: Transform::from_xyz(-1.0, 0.0, 0.0),
..default()
},
));
I get:
ERROR bevy_asset::server: Requested handle of type TypeId { t: 20984825428628115851185960703696596255 } for asset 'B.glb' does not match actual asset type 'bevy_gltf::Gltf', which used loader 'bevy_gltf::loader::GltfLoader'
So I'm guessing bevy_asset_loader is doing something more complicated under the hood than I expect
I can reproduce the issue with your repository. This is the generated AssetCollection
impl:
impl AssetCollection for SceneAssets {
fn create(world: &mut ::bevy::ecs::world::World) -> Self {
let from_world_fields = ();
world
.resource_scope(|
world,
asset_keys: ::bevy::prelude::Mut<
::bevy_asset_loader::dynamic_asset::DynamicAssets,
>|
{
SceneAssets {
scene_a: {
let asset_server = world
.get_resource::<::bevy::asset::AssetServer>()
.expect("Cannot get AssetServer");
asset_server.load("A.glb")
},
scene_b: {
let asset_server = world
.get_resource::<::bevy::asset::AssetServer>()
.expect("Cannot get AssetServer");
asset_server.load("B.glb")
},
}
})
}
fn load(
world: &mut ::bevy::ecs::world::World,
) -> Vec<::bevy::prelude::UntypedHandle> {
let cell = world.cell();
let asset_server = cell
.get_resource::<::bevy::prelude::AssetServer>()
.expect("Cannot get AssetServer");
let asset_keys = cell
.get_resource::<bevy_asset_loader::prelude::DynamicAssets>()
.expect("Cannot get bevy_asset_loader::prelude::DynamicAssets");
let mut handles = ::alloc::vec::Vec::new();
handles.push(asset_server.load_untyped("A.glb").untyped());
handles.push(asset_server.load_untyped("B.glb").untyped());
handles
}
}
The only difference to what you tried to do in Bevy directly seems to be the use of load_untyped
. Maybe there is some issue with handle reusage :thinking:
Interesting (TIL about cargo expand
). So you are loading it twice (once untyped in load
and once normally in create
)? I would've expected it to get the handle in create
from the LoadingAssetHandles
or something like that.
I was able to repro without bevy_asset_loader: https://github.com/bevyengine/bevy/issues/11509 In the meantime I think we should be able to come up with a workaround
So you are loading it twice (once untyped in load and once normally in create)? I would've expected it to get the handle in create from the LoadingAssetHandles or something like that.
The actual loading should only happen once since Bevy keeps assets in memory as long as we keep a Handle. LoadingAssetHandles contains only untyped handles and no easy mapping from paths, while load
will directly use the right handle type based on the collection resource.
In the meantime I think we should be able to come up with a workaround
The "workaround" would be to use the #Scene0
label in my opinion. Is there a reason you do not use it?
Thanks, that makes sense.
The "workaround" would be to use the #Scene0 label in my opinion. Is there a reason you do not use it?
I used to but since the 0.12 update it seems not possible anymore to use #Scene0 with bevy_gltf_components (for context https://github.com/kaosat-dev/Blender_bevy_components_workflow/issues/102#issuecomment-1902772089).
Closing as it's not a bevy_asset_loader issue