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

如何在Bevy中为GLTF场景添加父实体并挂载ComponentFoo?

Hey, let's break down what's going on here and fix your problem step by step.

First, the error you're seeing (Cannot add component because the 'current entity' is not set) happens because commands.spawn_scene() doesn't create a single parent entity for your GLTF scene. Instead, it directly spawns all the entities from the GLTF file into the world—there's no "current entity" to attach your ComponentFoo to when you chain .with(). current_entity().unwrap() also fails for the same reason: there's no active entity being spawned in that chain.

1. Get a Parent Entity for Your GLTF Scene (and Attach ComponentFoo Directly)

The right way to get a controllable parent entity for your entire scene is to use SceneBundle instead of spawn_scene(). This creates a root entity that all GLTF scene entities will be parented to, and you can attach your component directly to this root:

use bevy::prelude::*;

// Your custom component
#[derive(Component)]
struct ComponentFoo;

fn load_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
    // Load the GLTF asset
    let gltf_handle = asset_server.load("models/FlightHelmet/FlightHelmet.gltf");
    // Spawn a root entity with SceneBundle and your component
    let scene_root_entity = commands.spawn((
        SceneBundle {
            // Extract the Scene handle from the GLTF asset
            scene: gltf_handle.typed::<Scene>(),
            transform: Transform::default(),
            ..Default::default()
        },
        ComponentFoo {}, // Attach your component here!
    )).id();

    // Now you have the root entity stored in scene_root_entity for later use
}

This root entity comes with Transform and GlobalTransform out of the box, and every entity from your GLTF scene will be its child. Perfect for what you need.

2. Traverse All Entities in the Scene

If you need to iterate over every entity in the GLTF scene, you have two reliable options:

Option A: Recurse Through the Root Entity's Children

Since all scene entities are children of the root you spawned, you can use a Query<&Children> to walk the hierarchy:

fn traverse_scene(
    root_entity: Entity,
    children_query: &Query<&Children>,
    // Use a closure to handle each entity
    mut handler: impl FnMut(Entity),
) {
    // Process the current entity first
    handler(root_entity);
    // Recursively process all children
    if let Ok(children) = children_query.get(root_entity) {
        for &child in children {
            traverse_scene(child, children_query, &mut handler);
        }
    }
}

// Example usage in a system:
fn process_scene_entities(
    scene_root_entity: Res<YourSceneRootResource>, // Store the root entity in a resource
    children_query: Query<&Children>,
    mut transform_query: Query<&mut Transform>,
) {
    traverse_scene(scene_root_entity.0, &children_query, |entity| {
        // Do something with each entity, e.g. print its ID or modify its transform
        println!("Scene entity ID: {:?}", entity);
        if let Ok(mut transform) = transform_query.get_mut(entity) {
            // Adjust transform if needed
        }
    });
}

Option B: Filter by SceneInstance Component

If you used spawn_scene() (and don't have a root entity), every entity from the scene will have a SceneInstance component linking it to the original scene handle. You can query for these:

fn get_all_scene_entities(
    target_scene: Handle<Scene>,
    query: Query<(Entity, &SceneInstance)>,
) -> Vec<Entity> {
    query.iter()
        .filter(|(_, instance)| instance.scene == target_scene)
        .map(|(entity, _)| entity)
        .collect()
}

3. Locate the GLTF's Root Transform Entity

If you did use spawn_scene() and need to find the top-level transform entity from the GLTF file (not a manually created root), look for an entity with Transform that has no parent (i.e., no Parent component) and belongs to your scene:

fn find_gltf_root_transform(
    target_scene: Handle<Scene>,
    query: Query<(Entity, &Transform, &SceneInstance)>,
    parent_query: Query<&Parent>,
) -> Option<Entity> {
    query.iter()
        .filter(|(_, _, instance)| instance.scene == target_scene)
        // Find entities that don't have a parent
        .find(|(entity, _, _)| !parent_query.contains(*entity))
        .map(|(entity, _, _)| entity)
}

But again, using SceneBundle to create your own root entity is better—it gives you explicit control, no need to hunt for the root later.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:07:59