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

Correct process to add a Collider #504

Closed
bas-ie opened this issue Jan 3, 2024 · 5 comments
Closed

Correct process to add a Collider #504

bas-ie opened this issue Jan 3, 2024 · 5 comments

Comments

@bas-ie
Copy link
Contributor

bas-ie commented Jan 3, 2024

Hello and thank you for bevy_ecs_tilemap! I'm playing with tilemaps and bevy_xpbd, and I wonder if perhaps this is just inexperience or if I'm encountering a side effect of #500, but I'm having a hard time getting tiles in a tilemap to collide with a player object (just a 2d mesh with a transform, an xpbd RigidBody::Dynamic and an xpbd Collider).

Given something like this, I notice there are invisible colliders in the middle of the tilemap square, but nothing around its edges:

fn generate_level_map(asset_server: Res<AssetServer>, mut commands: Commands) {
    let tilemap_entity = commands.spawn_empty().id();
    let map_size = TilemapSize { x: 64, y: 64 };
    let texture_handle = asset_server.load("textures/tiles.png");
    let map_type = TilemapType::Square;
    let tile_size = TilemapTileSize { x: 16., y: 16. };
    let grid_size = tile_size.into();

    // Each room can have its own tilemap, at least for now.
    let mut room_storage = TileStorage::empty(map_size);

    for x in 0..map_size.x {
        for y in 0..map_size.y {
            if x == 0 || x == map_size.x - 1 || y == 0 || y == map_size.y - 1 {
                let tile_pos = TilePos { x, y };
                let center = tile_pos.center_in_world(&grid_size, &map_type);

                let tile_entity = commands
                    .spawn((
                        RigidBody::Static,
                        Collider::cuboid(16., 16.),
                        SpatialBundle::from_transform(Transform::from_xyz(center.x, center.y, 0.)),
                        TileBundle {
                            position: tile_pos,
                            tilemap_id: TilemapId(tilemap_entity),
                            ..Default::default()
                        },
                    ))
                    .id();
                room_storage.set(&tile_pos, tile_entity);
            }
        }
    }

    let transform = get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0);

    commands.entity(tilemap_entity).insert(TilemapBundle {
        grid_size,
        map_type,
        size: map_size,
        storage: room_storage,
        texture: TilemapTexture::Single(texture_handle),
        tile_size,
        transform,
        ..Default::default()
    });

    #[cfg(all(not(feature = "atlas"), feature = "render"))]
    {
        array_texture_loader.add(TilemapArrayTexture {
            texture: TilemapTexture::Single(asset_server.load("textures/tiles.png")),
            tile_size,
            ..Default::default()
        });
    }
}

(adapted from the basic example). I'd be happy to contribute an example once I get all this cleared up, but it's entirely possible I've just misunderstood the basics. Any pointers to examples or clarifying where I'm going wrong would be super helpful.

image

(screenshot shows player in green, enemy in red, tile "wall" in orange and obviously not colliding with anything).

@rparrett
Copy link
Collaborator

rparrett commented Jan 3, 2024

Adding a physics debug visualization will help you here. Here's how to do that in bevy_xpbd.

Your issue seems to be that your Tilemap has a transform that our individual tiles aren't inheriting. You can either add

commands.entity(tilemap_entity).add_child(tile_entity);

to your tile spawning code, or remove the offset from the Tilemap.

@bas-ie
Copy link
Contributor Author

bas-ie commented Jan 3, 2024

That's immediately so much clearer! Colliders were nowhere near the tiles.

image

Adding the tile as a child of the map works a treat (I wasn't sure how to go about removing the offset). Thanks so much for your help.

Would a simple example of tile collision be useful, or is it a bit much given it'd add bevy_xpbd as a dev dependency?

@rparrett
Copy link
Collaborator

rparrett commented Jan 3, 2024

or is it a bit much given it'd add bevy_xpbd as a dev dependency?

I know @StarArawn has been contemplating removing the tiled and ldtk examples recently, with the goal of reducing the scope of this project a bit. So I think that a PR like that would be unlikely to get merged. It seems like a useful example to show the world, but maybe not as an example in this repository.

@bas-ie
Copy link
Contributor Author

bas-ie commented Jan 3, 2024

Exactly right. I might chuck something in a gist and link it from here, should be sufficient documentation.

@bas-ie
Copy link
Contributor Author

bas-ie commented Jan 4, 2024

This should do the trick: https://github.com/richchurcher/tile_collision_example_xpbd

Cheers!

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

2 participants