janhohenheim / foxtrot

The all-in-one Bevy 3D game template for desktop.
Apache License 2.0
610 stars 44 forks source link

RepeatedMaterial example #273

Closed teenangst closed 8 months ago

teenangst commented 1 year ago

I have been trying to get RepeatedMaterial to work but without examples I'm going around in circles. I'm new to Bevy and just need a repeating texture in 2D. For a while I found that I wasn't actually adding the material to the repeated HashMap and just to an Assets not related to it, but I have no idea how to add the material to the HashMap without being told that the resource requested doesn't exist. I went through your projects to see if you used it and I couldn't see any usage but I probably have just been searching wrong.

I'm sure there's lots wrong but I tried, considering that the error I get from this is "entered unreachable code" [bevy_ecs-0.10.1\src\schedule\executor\multi_threaded.rs:459:45] I've really messed things up

fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut materials: ResMut<Assets<RepeatedMaterial>>,
    mut repeated_materials: ResMut<Materials>,
    mut meshes: ResMut<Assets<Mesh>>
) {

    let asset: Handle<Image> = asset_server.load("sprites/air.png");
    let handle = asset.id();
    let repeats = Repeats {
        horizontal: 10,
        vertical: 10,
    };
    let material = RepeatedMaterial {
        texture: Some(asset),
        repeats: repeats
    };

    let material_handle = materials.add(material);

    commands.spawn(
        MaterialMeshBundle {
            transform: Transform::from_xyz(0.0, 0.0, 0.),
            mesh: meshes.add(
                Mesh::from(shape::Quad {
                    size: Vec2::new(100.0, 100.0),
                    flip: false
                })
            ),
            material: repeated_materials.repeated.insert((handle, repeats), material_handle).unwrap(),
            ..default()
        }
    );
}

I don't know what I'm doing, I expect that the intended solution is far simpler. I would really appreciate an example

janhohenheim commented 8 months ago

Tiling textures have always been a big of a problem for Bevy (see https://github.com/bevyengine/bevy/issues/399). I have decided to remove the shader for repeated textures and simply resize the UV of the ground texture to make it be repeated. If you need any help with that new approach, feel free to ask. As for your code you posted, try the solution in the linked issue:

    let sampler_desc = ImageSamplerDescriptor {
        address_mode_u: ImageAddressMode::Repeat,
        address_mode_v: ImageAddressMode::Repeat,
        ..Default::default()
    };

    let settings = move |s: &mut ImageLoaderSettings| {
        s.sampler = ImageSampler::Descriptor(sampler_desc.clone());
    };

    let texture_handle = assets.load_with_settings("sprites/air.png", settings);