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!
Logic Projects on YouTube has a RPG they’re working on that could be relevant to you.
I’ve tried something myself and ended up writing my own data structures to hold handles to the sprites and change them as necessary. But that’s a lot of work still and not sure if it’s the best long-term.
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 :(