bevy
bevy copied to clipboard
AssetServer doesn't work in `FromWorld`
Bevy version
0.12.1
Relevant system information
MacOs Intel
`AdapterInfo { name: "AMD Radeon Pro 5300M", vendor: 0, device: 0, device_type: DiscreteGpu, driver: "", driver_info: "", backend: Metal }`
What you did
I have a resource storing some materials called MapAssets
:
#[derive(Resource)]
pub struct MapAssets {
pub mat: Handle<StandardMaterial>
}
This material uses a base_color_texture
loaded from the assets/
folder.
If I load that texture in my FromWorld
impl
impl FromWorld for MapAssets {
fn from_world(world: &mut World) -> Self {
let server = world.resource::<AssetServer>();
let texture = server.load("my_texture.png);
let mut materials = world.resource_mut::<Assets<StandardMaterial>>;
let mat = materials.add(StandardMaterial::from(texture));
Self { mat }
}
}
The object is invisible.
On the other hand if I use a Startup
system using Res<AssetServer>
and insert the resource through Commands
it works as expected.
Are you able to reproduce with this code based on the 3d_scene
example? I had to modify your code slightly to make it compile.
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.init_resource::<MapAssets>()
.run();
}
#[derive(Resource)]
pub struct MapAssets {
pub mat: Handle<StandardMaterial>,
}
impl FromWorld for MapAssets {
fn from_world(world: &mut World) -> Self {
let server = world.resource::<AssetServer>();
let texture = server.load("branding/icon.png");
let mut materials = world.resource_mut::<Assets<StandardMaterial>>();
let mat = materials.add(StandardMaterial::from(texture));
Self { mat }
}
}
fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, map_assets: Res<MapAssets>) {
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: map_assets.mat.clone(),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
});
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
}
On my end (MacOS, M1), Bevy 0.12.1, I am seeing a cube (no problem).
edit: Oops, previous version of this comment had code compatible with Bevy main.
I ran this and no cube is visible
That's weird because something like this seems to work:
#[derive(Resource)]
pub struct UiAssets {
pub font: Handle<Font>,
}
impl FromWorld for UiAssets {
fn from_world(world: &mut World) -> Self {
let asset_server: &AssetServer = world.resource();
Self {
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
}
}
}
(source: https://github.com/TanTanDev/no_communication_0/blob/4d6983ea152bf140046cd20953ff4a6b22503679/src/ui_util.rs#L19)
I suspect it has something to do with the nested handle: Handle<StandardMatierial>
stores a Handle<Image>
.
For example if I run the code of @rparrett with bevy_inspector_egui
, the material exists but the texture field is blank, not even the default white square.
I just hit the same bug (on 0.13), and I don't have any nesting, just a Handle<Image>
inside a custom Resource
. I need to upgrade to 0.14 see if that changes anything, but the symptoms are exactly the same, loading from a Startup
system works but not from FromWorld::from_world()
.