Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading custom sprite assets #236

Open
musjj opened this issue Oct 12, 2023 · 3 comments
Open

Loading custom sprite assets #236

musjj opened this issue Oct 12, 2023 · 3 comments

Comments

@musjj
Copy link

musjj commented Oct 12, 2023

I'm trying to use bevy_aseprite to load my player sprite. It looks like that this crate heavily relies on macros in order to load entity assets, so I'm not sure how to integrate it.

The bevy_aseprite library requires the user to have the following bundle in the entity:

pub struct AsepriteBundle {
    pub transform: Transform,
    pub global_transform: GlobalTransform,
    pub animation: AsepriteAnimation,
    pub aseprite: Handle<Aseprite>, // <- The asset
}

Since you're not supposed to spawn the entities manually, how do I pass the asset into the bundle? Do I need to make a custom macro for this?

@Trouv
Copy link
Owner

Trouv commented Oct 13, 2023

You can actually use a custom implementation of LdtkEntity for this. Since AsepriteBundle is a foreign type, you'll need to wrap it in a local type to implement a foreign trait like LdtkEntity on it, but it is doable. It does give you access to the asset server:

#[derive(Default, Bundle)]
pub struct PlayerBundle {
    aseprite_bundle: AsepriteBundle
    // other player components..
}

impl LdtkEntity for PlayerBundle {
    fn bundle_entity(
        entity_instance: &EntityInstance,
        layer_instance: &LayerInstance,
        tileset: Option<&Handle<Image>>,
        tileset_definition: Option<&TilesetDefinition>,
        asset_server: &AssetServer,
        texture_atlases: &mut Assets<TextureAtlas>
    ) -> Self {
        // build your PlayerBundle here
    }
}

You also have other options than the macros when spawning entities, and it's definitely not ideal when you need more access to the world than the macros/LdtkEntity trait provides. A common pattern is the "blueprint pattern", where you have the plugin spawn a smaller or marker component on your entity, and then you do some post-processing on it in a normal bevy system.

#[derive(Default, Component)]
struct PlayerMarker;

// register this to the app via one of the LdtkEntityAppExt methods 
#[derive(Default, Bundle, LdtkEntity)]
struct PlayerBundle {
    marker: PlayerMarker,
}

fn add_aseprite_to_player(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    player_query: Query<(Entity, &Transform), Added<PlayerMarker>>
) {
    // add any component/bundle you want to the player, with access to the asset server
}

Personally I prefer doing the latter since implementing LdtkEntity manually is a bit verbose and doesn't give you much access to the world if you need it, but for the time being it is more convenient for getting access to most relevant LDtk data.

@musjj
Copy link
Author

musjj commented Oct 13, 2023

Thanks, I'll go with the second method. There's this issue: #177, but will the workflow for this kind of stuff improve in the future? I feel that expecting the user to always use SpriteSheetBundle is a bit too restrictive.

@Trouv
Copy link
Owner

Trouv commented Oct 14, 2023

It will. However, it might not be in the form #177 is proposing. Right now I'm gradually working on improving the "blueprint pattern" (in particular, making it easier to access LDtk asset data from normal systems). I don't really expect users to always use a SpriteSheetBundle, it's just a common use case so the plugin provides an attribute macro for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants