我是游戏开发和Rust的新手,所以我可能走错了路。我使用bevy 0.10.1、bevy_ecs_tilemap、bevy_rapier2d和tiled来创建一个包含.tsx文件中指定的冲突的tilemap。我的一些瓷砖使用多边形来定义碰撞对象。我能够让矩形碰撞工作,但多边形碰撞是在错误的位置,有时错误的形状。
if let Some(object_layer) = layer_tile.collision.clone() {
let shapes = object_layer
.object_data()
.iter()
.filter_map(|object_data| {
let pos = Vect::new(object_data.x / 2., -object_data.y / 2.);
let rot = object_data.rotation;
let shape = match &object_data.shape {
tiled::ObjectShape::Rect { width, height } => {
Collider::cuboid(width / 2., height / 2.)
}
tiled::ObjectShape::Ellipse { width, height } => {
Collider::capsule_x(width / 2., height / 2.)
}
tiled::ObjectShape::Polyline { points } => {
Collider::polyline(
points
.iter()
.map(|(x, y)| Vect::new(*x, *y))
.collect(),
None,
)
}
tiled::ObjectShape::Polygon { points } => {
Collider::convex_hull(
&points
.iter()
.map(|(x, y)| Vect::new(*x, *y))
.collect::<Vec<_>>(),
)?
}
_ => {
return None;
}
};
Some((pos, rot, shape))
})
.collect::<Vec<_>>();
let world_pos = tile_pos.center_in_world(&grid_size, &map_type);
let transform =
get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.)
* Transform::from_xyz(
world_pos.x + offset_x,
world_pos.y - offset_y,
0.,
);
if shapes.len() == 1 {
let (pos, rot, collider) = shapes[0].clone();
let transform = transform
* Transform {
translation: Vec3::new(pos.x, pos.y, 0.),
rotation: Quat::from_rotation_x(rot),
..default()
};
commands
.entity(tile_entity)
.insert((collider, TransformBundle::from_transform(transform)));
} else if shapes.len() > 1 {
commands.entity(tile_entity).insert((
Collider::compound(shapes),
TransformBundle::from_transform(transform),
));
}
}
如何将平铺的多边形碰撞数据转换为Rapier碰撞器?还是我把不属于我的工具组合在一起了?
1条答案
按热度按时间rm5edbpk1#
经过多次试验和错误,我想出了如何做到这一点。多边形是颠倒的,我需要把矩形和多边形区别对待。(我的平铺图目前没有椭圆或折线,所以我假设它们的工作原理与其他形状相同。)