Unable to define textures for `StandardMaterial` assets within `bsn!` macro
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version and features
Bevy 0.19
## What you did
I'm loving the new `bsn!` macro, but I've been running into problems trying to define `StandardMaterial` with image assets:
```rust
fn spawn_capsule() -> impl Scene {
bsn! {
Mesh3d(asset_value(Capsule3d { radius: 0.5, half_length: 0.5 }))
MeshMaterial3d::(asset_value(StandardMaterial {
base_color_texture: Some("checkered_texture_blue.png"),
..default()
}))
}
}
```
## What went wrong
It's surprising\* to me that `Option<&'static str>` -> `Option>` doesn't work like `&'static str` -> `Handle`.
```
| base_color_texture: Some("checkered_texture_blue.png"),
| ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Handle`, found `&str`
| |
| arguments to this enum variant are incorrect
|
= note: expected enum `bevy::bevy_asset::Handle`
found reference `&'static str`
help: the type constructed contains `&'static str` due to the type of the argument passed
--> src/main.rs:45:33
|
| base_color_texture: Some("checkered_texture_blue.png"),
| ^^^^^----------------------------^
| |
| this argument influences the type of `Some`
```
\* Surprising to me as a BSN noob :)
## Additional information
As far as I can tell, the problem lies with `StandardMaterial` not specifying its own `FromTemplate` and relying on the one generated for `Default` & `Clone` instead. As a consequence, the BSN macro tries to resolve the value normally as a literal `Option<&'static str>`, rather than using `.into()` on the wrapped string.
Right now, I can workaround this with a small helper:
```rust
fn spawn_capsule() -> impl Scene {
bsn! {
Mesh3d(asset_value(Capsule3d { radius: 0.5, half_length: 0.5 }))
image_texture_material("checkered_texture_blue.png")
}
}
fn image_texture_material(path: &'static str) -> impl Scene {
template(move |ctx| {
let image_texture = ctx.resource::().load(path);
let material_handle =
ctx.resource_mut::>()
.add(StandardMaterial {
base_color_texture: Some(image_texture),
..default()
});
Ok(MeshMaterial3d::(material_handle))
})
}
```
However this is less than ideal since I can no longer (easily) update individual fields on the StandardMaterial from my Scene Constructors.
Contributor guide
Research direction
Start with the bsn! macro's handling of StandardMaterial and its generated FromTemplate implementations, then compare that path with the asset_value and template entry points shown here. Done means an Option<&'static str> texture value is converted to Option> within bsn! while preserving the ability to update other StandardMaterial fields; verify against the reported Bevy 0.19 example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 56/100