NiklasEi / bevy_asset_loader

Bevy plugin helping with asset loading and organization
Apache License 2.0
481 stars 53 forks source link

How can I load a custom asset that contains asset keys? #137

Closed zainthemaynnn closed 1 year ago

zainthemaynnn commented 1 year ago

I have a custom asset that contains fields that referring to the keys of other assets in the assets file. is there a way I can get the handle corresponding to that key? for example, in the code below, converting RawAsset.other_key to a ProcesssedAsset.other_handle.

({
    "other_asset.0": OtherAsset ( /* ... */ ),
    "combined_asset": RawAsset (
        text: "xxxxx",
        other_key: "other_asset.0",
    ),
})
#[derive(Debug, Deserialize)]
struct RawAsset {
    text: String,
    other_key: String,
}

#[derive(TypeUuid)]
#[uuid = "18dc82eb-d5f5-4d72-b0c4-e2b234367c36"]
struct ProcessedAsset {
    text: String,
    other_handle: Handle<OtherAsset>,
}

// `DynamicAsset::build` impl for `ProcessedAsset`
let world_cell = world.cell();
let RawAsset { text, other_key } = self;
let mut assets = world_cell.resource_mut::<Assets<ProcessedAsset>>();

let DynamicAssetType::Single(handle) = world_cell.resource::<DynamicAssets>().get_asset(other_key).unwrap().build(world)?;
Ok(DynamicAssetType::Single(assets.add(ProcessedAsset { text, other_handle: handle.typed() }));

this works but I think this adds a completely new OtherAsset every time I get the handle? additionally it's impossible to get the handle in DynamicAsset::load.

NiklasEi commented 1 year ago

You could split loading of Other and Raw assets into two loading states. Then all your other assets get loaded once and you can retrieve the handles from a resource when loading the raw assets. Would that work for your use case?

zainthemaynnn commented 1 year ago

yes, thanks. I ended up doing this along with enums pointing to the preloaded handles instead of string keys.