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!
deleted by creator
Hello! So I ended up fixing this issue with sprite loading and figured out how to load multiple sprites in the scene. It turns out that I can’t load the images and then spawn in the sprite objs in the same function because of Rust rules 🤷
Anyhow, I am having a different issue now, and I’ve made a new post about it here.
You should probably ask over here as well: https://github.com/FraserLee/bevy_sprite3d/issues I havent used this library before but I might take a look once Im out of the bath
ok so I’m out of the bath.
#[derive(SystemParam)] pub struct Sprite3dParams<'w, 's> { pub meshes : ResMut<'w, Assets<Mesh>>, pub materials : ResMut<'w, Assets<StandardMaterial>>, pub images : ResMut<'w, Assets<Image>>, pub atlases : ResMut<'w, Assets<TextureAtlas>>, pub sr : ResMut<'w, Sprite3dRes>, #[system_param(ignore)] marker: PhantomData<&'s usize>, }
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 :(