You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:32:02