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!

  • Cass.Forest@beehaw.orgOP
    link
    fedilink
    English
    arrow-up
    2
    ·
    1 year ago

    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!