Bevy 0.15:如何为选中实体添加Wireframe线框组件
解决Bevy 0.15点击实体显示线框的问题
核心问题分析
你遇到的线框不显示问题,本质是Wireframe组件加错了实体:通过SceneRoot加载GLB模型时,模型的MeshMaterial3d组件是挂载在场景的子实体上的,而你给父实体添加Wireframe组件,渲染系统无法识别。另外,自定义Controllable结构体里的_wireframe字段只是普通变量,Bevy的渲染系统不会读取它,必须将Wireframe作为组件直接添加到带网格的实体上才会生效。
具体修复步骤
1. 启用Wireframe插件
首先确保在App初始化时添加Wireframe插件,否则线框渲染功能不会生效:
use bevy::wireframe::WireframePlugin; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(WireframePlugin) // 必须添加这个插件 // ... 其他插件和系统注册 .run(); }
2. 修改点击事件处理逻辑
点击父实体后,需要遍历其所有子实体,找到带有MeshMaterial3d的实体,给这些子实体添加Wireframe组件:
fn on_click_controllable( click: Trigger<Pointer<Click>>, mut commands: Commands, children_query: Query<&Children>, mesh_entity_query: Query<Entity, With<MeshMaterial3d<StandardMaterial>>>, ) { // 广度优先遍历所有子实体,找到带网格的目标实体 let mut entity_queue = vec![click.entity()]; while let Some(current_entity) = entity_queue.pop() { // 如果当前实体挂载了网格组件,添加Wireframe if mesh_entity_query.contains(current_entity) { commands.entity(current_entity).insert(Wireframe); } // 继续遍历子实体 if let Ok(children) = children_query.get(current_entity) { entity_queue.extend(children.iter().copied()); } } println!("{} was clicked", click.entity()); }
3. 清理无效代码
- 删除
Controllable结构体里的_wireframe字段,它对渲染没有任何作用:
struct Controllable { _mesh: MeshMaterial3d<StandardMaterial>, _collider: Collider, _transform: Transform, _rapier_pickable: RapierPickable, }
- 移除无用的
wireframe_entities系统,直接通过点击事件添加组件即可,不需要额外查询修改自定义字段。
4. 修正实体生成时的Observer绑定
你原来的代码给同一个实体绑定了两个点击处理逻辑,会导致重复触发。保留一个即可:
let entity = commands .spawn(( SceneRoot(asset_server.load(GltfAssetLabel::Scene(0).from_asset("guy.glb"))), Controllable { _mesh: MeshMaterial3d(debug_material.clone()), _collider: Collider::cuboid(2.5, 0.01, 2.5), _transform: Transform::from_xyz(0.0, 0.0, 3.0), _rapier_pickable: RapierPickable, }, )) .id(); // 只绑定一次点击处理逻辑 commands.entity(entity).observe(on_click_controllable);
额外说明
- Bevy的组件是实体绑定的,只有添加到对应实体上的组件才会被系统识别,自定义结构体里的字段无法替代组件的作用。
- 对于场景加载的模型,一定要注意实体层级,渲染相关的组件(比如
Wireframe、Material)必须和Mesh或MeshMaterial3d在同一个实体上才能生效。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

