Use material name for mesh entity's Name when available (#19287)

# Objective

Fixes #19286

## Solution

Use material name for mesh entity's Name when available

## Testing

Test code, modified from examples/load_gltf.rs
```rust
//! Loads and renders a glTF file as a scene.

use bevy::{gltf::GltfMaterialName, prelude::*, scene::SceneInstanceReady};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_observer(on_scene_load)
        .run();
}

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
    ));

    commands.spawn((DirectionalLight {
        shadows_enabled: true,
        ..default()
    },));

    commands.spawn(SceneRoot(asset_server.load(
        GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"),
    )));
}

fn on_scene_load(
    trigger: Trigger<SceneInstanceReady>,
    children: Query<&Children>,
    names: Query<&Name>,
    material_names: Query<&GltfMaterialName>,
) {
    let target = trigger.target();

    for child in children.iter_descendants(target) {
        let name = if let Ok(name) = names.get(child) {
            Some(name.to_string())
        } else {
            None
        };
        let material_name = if let Ok(name) = material_names.get(child) {
            Some(name.0.clone())
        } else {
            None
        };

        info!("Entity name:{:?} | material name:{:?}", name, material_name);
    }
}
```

---

## Showcase

Run log:
<img width="859" alt="Image"
src="https://github.com/user-attachments/assets/87daddf3-31e6-41f8-9be2-4b292da9b75a"
/>

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Greeble <166992735+greeble-dev@users.noreply.github.com>
This commit is contained in:
DaoLendaye 2025-05-20 22:45:04 +08:00 committed by GitHub
parent 55edb0b476
commit c62ca1a0d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 20 additions and 6 deletions

View File

@ -1,13 +1,17 @@
use bevy_mesh::PrimitiveTopology;
use gltf::mesh::{Mesh, Mode, Primitive};
use gltf::{
mesh::{Mesh, Mode},
Material,
};
use crate::GltfError;
pub(crate) fn primitive_name(mesh: &Mesh<'_>, primitive: &Primitive) -> String {
pub(crate) fn primitive_name(mesh: &Mesh<'_>, material: &Material) -> String {
let mesh_name = mesh.name().unwrap_or("Mesh");
if mesh.primitives().len() > 1 {
format!("{}.{}", mesh_name, primitive.index())
if let Some(material_name) = material.name() {
format!("{}.{}", mesh_name, material_name)
} else {
mesh_name.to_string()
}

View File

@ -1464,10 +1464,11 @@ fn load_node(
}
if let Some(name) = material.name() {
mesh_entity.insert(GltfMaterialName(String::from(name)));
mesh_entity.insert(GltfMaterialName(name.to_string()));
}
mesh_entity.insert(Name::new(primitive_name(&mesh, &primitive)));
mesh_entity.insert(Name::new(primitive_name(&mesh, &material)));
// Mark for adding skinned mesh
if let Some(skin) = gltf_node.skin() {
entity_to_skin_index_map.insert(mesh_entity.id(), skin.index());

View File

@ -0,0 +1,9 @@
---
title: Use Gltf material names for spawned primitive entities
authors: ["@rendaoer"]
pull_requests: [19287]
---
When loading a Gltf scene in Bevy, each mesh primitive will generate an entity and store a `GltfMaterialName` component and `Name` component.
The `Name` components were previously stored as mesh name plus primitive index - for example, `MeshName.0` and `MeshName.1`. To make it easier to view these entities in Inspector-style tools, they are now stored as mesh name plus material name - for example, `MeshName.Material1Name` and `MeshName.Material2Name`.