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

Bevy Rust中如何在Mesh创建后逐帧修改网格数据

问题根源

报错核心是资源访问权限声明错误:update_planets系统中Assets<Mesh>资源被声明为只读访问的Res<Assets<Mesh>>,Res类型仅提供资源的不可变引用,未实现可变解引用所需的DerefMut trait,因此无法调用需要&mut self的get_mut方法。
另外原代码还存在几处笔误和类型不匹配问题,会在修复后一并解决。

修复方案
  • 将系统参数中的assets: Res<Assets<Mesh>>修改为mut assets: ResMut<Assets<Mesh>>,ResMut会为资源获取写锁,提供可变访问权限,支持调用get_mut等修改方法。
  • 修正代码中的笔误:删除无意义的handle.id调用(get_mut可直接传入Handle引用),替换未定义的temp、thingy变量为实际的有效变量。
  • 修正类型匹配问题:Mesh::ATTRIBUTE_POSITION属性接收的是Vec<[f32; 3]>类型数据,不要直接传入Vec<Vec3>,需将顶点坐标转为三元数组后再写入。
  • 优化匹配逻辑:直接对get_mut返回的Option做匹配,避免重复unwrap引发的运行时panic。
修正后的可运行代码
use bevy::{prelude::*, render::mesh::VertexAttributeValues};

fn setup (
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    let mesh = Mesh::from(shape::Icosphere { radius: 0.5, subdivisions: 10 });
    let colour = Color::srgb(0.2, 0.5, 0.8);

    commands.spawn(PbrBundle {
        mesh: meshes.add(mesh),
        material: materials.add(colour.into()),
        transform: Transform::from_xyz(0.0, 0.0, 0.0),
        ..Default::default()
    });
}

fn update_planets (
    mut query: Query<(&Transform, &Handle<Mesh>)>,
    mut assets: ResMut<Assets<Mesh>>
) {
    let (_transform, handle) = query.single().expect("场景中存在且仅存在一个行星实体");
    if let Some(mesh) = assets.get_mut(handle) {
        let positions = mesh.attribute(Mesh::ATTRIBUTE_POSITION).expect("Mesh缺少POSITION顶点属性");
        if let VertexAttributeValues::Float32x3(pos_data) = positions {
            let mut new_positions = Vec::with_capacity(pos_data.len());
            for pos in pos_data {
                let mut vertex_pos = Vec3::new(pos[0], pos[1], pos[2]);
                // 在此处编写自定义顶点修改逻辑,例如噪声形变、顶点动画等
                new_positions.push(vertex_pos.to_array());
            }
            mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, new_positions);
        }
    }
}
优化提示
  • Bevy 0.8及以上版本会自动检测Mesh资源的变更,自动将修改后的数据上传到GPU,无需手动添加变更标记。
  • 若多个实体共用同一个Mesh Handle,修改该Mesh会同步影响所有关联实体的显示效果;如果需要每个行星独立形变,生成实体时要为每个实体创建独立的Mesh副本,不要共用Handle。
  • 若查询中不需要修改Transform,不要使用get_single_mut,用single()获取只读查询结果即可,减少不必要的锁开销,提升系统调度效率。
  • 大顶点量的Mesh逐帧全量更新会产生较高的CPU-GPU传输开销,复杂形变逻辑建议迁移到GPU端用Compute Shader实现。

内容的提问来源于stack exchange,提问作者Xzenotrex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:03:15