-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a DynamicScene from a world and an entity root #6013
Conversation
|
||
/// To spawn a scene, you can use either: | ||
/// * [`SceneSpawner::spawn`](crate::SceneSpawner::spawn) | ||
/// * adding the [`SceneBundle`](crate::SceneBundle) to an entity | ||
/// * adding the [`Handle<Scene>`](bevy_asset::Handle) to an entity (the scene will only be | ||
/// visible if the entity already has [`Transform`](bevy_transform::components::Transform) and | ||
/// [`GlobalTransform`](bevy_transform::components::GlobalTransform) components) | ||
#[derive(Debug, TypeUuid)] | ||
#[derive(Debug, TypeUuid, Deref, DerefMut)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm reluctant to add these derives; they make things more implicit and are likely to break once we need to add more fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the Deref / DerefMut impls on Scene should be their own PR so they get appropriate review attention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'm reluctant to add these derives; they make things more implicit and are likely to break once we need to add more fields.
Then let's remove them later if we need to add more fields? For now they make working with scenes a lot nicer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disagreed. Why introduce extra implicitness and potential for future breaking changes, just to save on typing a .0
. I wouldn't call this "a lot nicer".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well then we're back to arguing against the Deref
derive that we promotes in Bevy: https://bevyengine.org/news/bevy-0-7/#deref-derefmut-derives
I'm not sure there are plans to add more fields to Scene
at the moment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm fine to leave it. We should write a manual Deref / DerefMut impl if and when we add more fields then, and call this out in the docs though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I don't think the Deref
/DerefMut
derives are needed. It's probably better for users to explicitly be aware that what they're working with is basically just a plain ol' World
. And yeah, it makes future additions to Scenes
less problematic (e.g. versioning, etc.).
/// Create a new dynamic scene from a given [`World`] at a given [`Entity`]. | ||
/// | ||
/// All descendants entities from the given one will be extracted. | ||
pub fn from_world_at_root( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bikeshed: i think the "at root" naming is confusing. I'd probably have called this from_world_entity_recursive
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
totally open to changing the name, even more if we change it to take several entities as input
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO from_entity_recursive
or from_entities_and_children
or something. I think the from_world
bit is unhelpful in context and can just be dropped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually cast my vote for a simple from_root
. Imo it's implicit that we're talking about worlds and entities here. If we want to be a little more specific, I think from_entity
is fine too— although, it could be slightly confusing as to whether this recurses into children or not.
Next best would probably be from_entity_recursive
.
|
||
/// To spawn a scene, you can use either: | ||
/// * [`SceneSpawner::spawn`](crate::SceneSpawner::spawn) | ||
/// * adding the [`SceneBundle`](crate::SceneBundle) to an entity | ||
/// * adding the [`Handle<Scene>`](bevy_asset::Handle) to an entity (the scene will only be | ||
/// visible if the entity already has [`Transform`](bevy_transform::components::Transform) and | ||
/// [`GlobalTransform`](bevy_transform::components::GlobalTransform) components) | ||
#[derive(Debug, TypeUuid)] | ||
#[derive(Debug, TypeUuid, Deref, DerefMut)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disagreed. Why introduce extra implicitness and potential for future breaking changes, just to save on typing a .0
. I wouldn't call this "a lot nicer".
/// All descendants entities from the given one will be extracted. | ||
pub fn from_world_at_root( | ||
world: &World, | ||
root: Entity, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I think this method would have limited practical utility. Who wants to create a scene from just one entity (+ children)? Sure, sometimes you might have such a use case, but it seems needlessly limited. What if you want a second entity? Or a few more?
Why not change this to impl IntoIterator<Item=Entity>
, allowing users to provide any number of root entities?
Would add a little extra complexity to the body of the function. Perhaps there should be some sort of deduplication logic to prevent redundant/duplicate entities in the scene. One suggestion might be to use an intermediary HashSet
instead of a Vec
. Or maybe we could just not do any deduplication (just accumulate all the entities into the scene without regard for duplicates), and document it as a caveat / leave it to the users to make sure they don't have duplicate entities in their list of roots.
It would make this function much more practical and useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you prefer to be able to append to an existing scene? Or just creating from multiple entities
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well now that you have said it ... i guess both? 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine single-entity scenes could be super useful for prefab-like serialization and usage.
But I agree it could also be useful to handle multiple at a time. Perhaps a method for a single root and another for multiple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. One thing I think we should add, though, is a new example that showcases both creating a scene from a root entity and also filtering by component (the latter could maybe go in the existing scene.rs
example if it's not too crowded).
@@ -20,6 +20,22 @@ pub struct DespawnChildrenRecursive { | |||
pub entity: Entity, | |||
} | |||
|
|||
/// List all descendants of a given entity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you expand on this? Specifically, is the returned Vec<Entity>
a depth-first traversal down the hierarchy or breadth-first?
@@ -76,17 +78,60 @@ impl DynamicScene { | |||
scene | |||
} | |||
|
|||
/// Create a new dynamic scene from a given [`World`] at a given [`Entity`]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
/// Create a new dynamic scene from a given [`World`] at a given [`Entity`]. | |
/// Create a new dynamic scene from a given [`World`] at a given [`Entity`] root. |
/// Create a new dynamic scene from a given [`World`] at a given [`Entity`]. | ||
/// | ||
/// All descendants entities from the given one will be extracted. | ||
pub fn from_world_at_root( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually cast my vote for a simple from_root
. Imo it's implicit that we're talking about worlds and entities here. If we want to be a little more specific, I think from_entity
is fine too— although, it could be slightly confusing as to whether this recurses into children or not.
Next best would probably be from_entity_recursive
.
/// All descendants entities from the given one will be extracted. | ||
pub fn from_world_at_root( | ||
world: &World, | ||
root: Entity, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine single-entity scenes could be super useful for prefab-like serialization and usage.
But I agree it could also be useful to handle multiple at a time. Perhaps a method for a single root and another for multiple?
let mut entities_of_interest = list_all_descendants(world, root); | ||
entities_of_interest.push(root); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This is more of a stylistic thing I suppose, but should the root come first in this list?
let mut entities_of_interest = list_all_descendants(world, root); | |
entities_of_interest.push(root); | |
let mut entities_of_interest = | |
std::iter::once(root).chain(list_all_descendants(world, root)); |
/// Write the dynamic entities and their corresponding components to the given world. | ||
/// | ||
/// This method will return a [`SceneSpawnError`] if a type either is not registered | ||
/// or doesn't reflect the [`Component`](bevy_ecs::component::Component) trait. | ||
pub fn write_to_world( | ||
pub fn write_to_world_with( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a separate method so users that want to extract everything can don't need to add the extra world.resource::<AppTypeRegistry>()
call.
/// Write the dynamic entities and their corresponding components to the given world. | ||
/// | ||
/// This method will return a [`SceneSpawnError`] if a type either is not registered | ||
/// or doesn't reflect the [`Component`](bevy_ecs::component::Component) trait. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation should include information about the registry filter.
|
||
/// To spawn a scene, you can use either: | ||
/// * [`SceneSpawner::spawn`](crate::SceneSpawner::spawn) | ||
/// * adding the [`SceneBundle`](crate::SceneBundle) to an entity | ||
/// * adding the [`Handle<Scene>`](bevy_asset::Handle) to an entity (the scene will only be | ||
/// visible if the entity already has [`Transform`](bevy_transform::components::Transform) and | ||
/// [`GlobalTransform`](bevy_transform::components::GlobalTransform) components) | ||
#[derive(Debug, TypeUuid)] | ||
#[derive(Debug, TypeUuid, Deref, DerefMut)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I don't think the Deref
/DerefMut
derives are needed. It's probably better for users to explicitly be aware that what they're working with is basically just a plain ol' World
. And yeah, it makes future additions to Scenes
less problematic (e.g. versioning, etc.).
Closed in favor of #6227. |
# Objective - make it easier to build dynamic scenes ## Solution - add a builder to create a dynamic scene from a world. it can extract an entity or an iterator of entities - alternative to #6013, leaving the "hierarchy iteration" part to #6185 which does it better - alternative to #6004 - using a builder makes it easier to chain several extractions
# Objective - make it easier to build dynamic scenes ## Solution - add a builder to create a dynamic scene from a world. it can extract an entity or an iterator of entities - alternative to bevyengine#6013, leaving the "hierarchy iteration" part to bevyengine#6185 which does it better - alternative to bevyengine#6004 - using a builder makes it easier to chain several extractions
# Objective - make it easier to build dynamic scenes ## Solution - add a builder to create a dynamic scene from a world. it can extract an entity or an iterator of entities - alternative to bevyengine#6013, leaving the "hierarchy iteration" part to bevyengine#6185 which does it better - alternative to bevyengine#6004 - using a builder makes it easier to chain several extractions
# Objective - make it easier to build dynamic scenes ## Solution - add a builder to create a dynamic scene from a world. it can extract an entity or an iterator of entities - alternative to bevyengine#6013, leaving the "hierarchy iteration" part to bevyengine#6185 which does it better - alternative to bevyengine#6004 - using a builder makes it easier to chain several extractions
# Objective - make it easier to build dynamic scenes ## Solution - add a builder to create a dynamic scene from a world. it can extract an entity or an iterator of entities - alternative to bevyengine#6013, leaving the "hierarchy iteration" part to bevyengine#6185 which does it better - alternative to bevyengine#6004 - using a builder makes it easier to chain several extractions
Objective
Scene
andDynamicScene
to have a more coherent API between the twoSolution
extract all registered components:
extract only a subset of components (here
Transform
):