So I'm currently working with Bevy to make a game with a style similar to that of Octopath Traveler. I'm using the bevy_sprite3d crate to render sprites in the 3D space. I'm currently working on writing the code for the battle scene of my JRPG. However, whenever I try to load multiple sprites into the scene, it gives me the following error:
error[B0002]: ResMut<bevy_asset::assets::Assets<bevy_sprite::texture_atlas::TextureAtlas>> in system load_sprites conflicts with a previous ResMut<bevy_asset::assets::Assets<bevy_sprite::texture_atlas::TextureAtlas>> access. Consider removing the duplicate access.
relevant system code
fn load_sprites(mut commands: Commands, asset_server: Res<AssetServer>, sprites_in_scene: Res<SpritesInScene>, mut texture_atlases: ResMut<Assets<TextureAtlas>>, mut sprite_params: Sprite3dParams) {
// Load first player sprite
commands.spawn(AtlasSprite3d {
atlas: texture_atlases.add(get_texture_atlas(&asset_server, sprites_in_scene.player_sprite1 /* u32 */, (37, 38), 19)),
pixels_per_metre: 32.,
partial_alpha: true,
unlit: true,
..default()
}.bundle(&mut sprite_params))
.insert(AnimationTimer(Timer::from_seconds(3. / 60., TimerMode::Repeating)))
.insert(Transform::from_xyz(-5., 0., 0.));
// Load second player sprite if it exists
if let Some(id) = sprites_in_scene.player_sprite2 {
commands.spawn(AtlasSprite3d {
atlas: texture_atlases.add(get_texture_atlas(&asset_server, id, (1, 1), 1)),
pixels_per_metre: 32.,
partial_alpha: true,
unlit: true,
..default()
}.bundle(&mut sprite_params))
.insert(AnimationTimer(Timer::from_seconds(3. / 60., TimerMode::Repeating)))
.insert(Transform::from_xyz(-2.5, 0., 0.));
}
// Load first enemy sprite
commands.spawn(AtlasSprite3d {
atlas: texture_atlases.add(get_texture_atlas(&asset_server, sprites_in_scene.enemy_sprite1 /* u32 */, (42, 42), 21)),
pixels_per_metre: 32.,
partial_alpha: true,
unlit: true,
..default()
}.bundle(&mut sprite_params))
.insert(AnimationTimer(Timer::from_seconds(3. / 60., TimerMode::Repeating)))
.insert(Transform::from_xyz(5., 0., 0.));
// Load second enemy sprite if it exists
if let Some(id) = sprites_in_scene.enemy_sprite2 {
commands.spawn(AtlasSprite3d {
atlas: texture_atlases.add(get_texture_atlas(&asset_server, id, (1, 1), 1)),
pixels_per_metre: 32.,
partial_alpha: true,
unlit: true,
..default()
}.bundle(&mut sprite_params))
.insert(AnimationTimer(Timer::from_seconds(3. / 60., TimerMode::Repeating)))
.insert(Transform::from_xyz(2.5, 0., 0.));
}
}
// The signature for get_texture_atlas:
fn get_texture_atlas(asset_server: &Res<AssetServer>, id: u32, tile_size: (u32, u32), row_num: usize) -> TextureAtlas
Am I doing this wrong? Is there a better way to load multiple texture atlases for the different entities in my battle scene? Thanks in advance!
ok so I'm out of the bath.
It seems like Sprite3dParams is already accessing
Assets<TextureAtlas>
which is why you get the the error. So you need to either removetexture_atlases
orsprite_params
. in your system.have you looked at this example? I won't be much help sorry :(
I have and I now understand why in that example, they split up asset loading and bundle spawning into two different systems. Note to self: it helps to check the source code of the stuff you use when it's available!