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

Support generic asset settings when loading an asset #243

Open
mgi388 opened this issue Nov 5, 2024 · 3 comments
Open

Support generic asset settings when loading an asset #243

mgi388 opened this issue Nov 5, 2024 · 3 comments

Comments

@mgi388
Copy link
Contributor

mgi388 commented Nov 5, 2024

Some asset formats like image have special treatment in this crate for configuring the asset on a per-asset-collection basis:

#[derive(AssetCollection, Resource)]
struct ImageAssets {
    #[asset(path = "images/pixel_tree.png")]
    #[asset(image(sampler = linear))]
    tree_linear: Handle<Image>,
}

But for many assets, you want to provide different settings for the same asset, depending on the asset collection. You can't rely on the asset meta file because you need different settings per asset collection.

For example, in an RTS game, during a level, you might want to load an asset for the Army. The Army asset itself has some settings that control whether additional assets are loaded. Those assets are not needed during the level, but are used in other scenes in the game. It would be good if bevy_asset_loader had a way to configure the assets settings near the #[asset] macro.

Even the GltfLoader inside Bevy has some settings, and you can imagine scenarios where you want to be able to configure these on a per-asset-collection basis:

pub struct GltfLoaderSettings {
    /// If true, the loader will spawn cameras for gltf camera nodes.
    pub load_cameras: bool,
    /// If true, the loader will spawn lights for gltf light nodes.
    pub load_lights: bool,
    /// If true, the loader will include the root of the gltf root node.
    pub include_source: bool,
}

I don't know what a solution looks like. It doesn't have to sit next to the #[asset] macro, but that seems like the most obvious ergonomic choice.

BTW, for DynamicAssets, there seems to be a way to achieve this already. Something like this:

When registering your asset:

dynamic_assets.register_asset(
    "foo",
    Box::new(WrappedFoo {
        path: "my/bar.foo",
        settings: FooLoaderSettings {
            load_a: true,
            load_b: false,
        },
    }),
);

And:

#[derive(Debug, Reflect)]
#[reflect(Debug)]
pub struct WrappedFoo {
    pub path: String,
    pub settings: FooLoaderSettings,
}

impl DynamicAsset for WrappedFoo {
    fn load(&self, asset_server: &AssetServer) -> Vec<UntypedHandle> {
        let settings = self.settings.clone();

        let foo_handle: Handle<OriginalFoo> =
            asset_server.load_with_settings(&self.path, move |s: &mut FooLoaderSettings| {
                *s = settings.clone();
            });

        vec![foo_handle.untyped()]
    }

    fn build(&self, world: &mut World) -> Result<DynamicAssetType, anyhow::Error> {
        let asset_server = world
            .get_resource::<AssetServer>()
            .expect("AssetServer resource should exist");
        Ok(DynamicAssetType::Single(
            asset_server.get_handle_untyped(&self.path).unwrap(),
        ))
    }
}

This seems to work AFAICT.

Originally raised in Discord.

@NWPlayer123
Copy link

I'm writing an AssetLoader for a custom model format and end-users having access to settings for configuring various aspects is rather important, especially since I want more complex behavior than bevy_gltf's simple on-off switches. Worth noting there was another issue a couple months ago that got closed, but clearly this is a needed feature.

@NiklasEi
Copy link
Owner

NiklasEi commented Jan 1, 2025

Maybe we could support any type of asset loader settings by accepting functions in the macro that return the settings. Comparable to what serde does for default values.

#215 was closed as completed because it asked for configuring the UV address mode of images through the asset macro. That is supported now.

@NWPlayer123
Copy link

That would definitely work for my use case. argh/argp does something similar to allow custom types when parsing command line args.

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

3 participants