Skip to content

Instantly share code, notes, and snippets.

@GianpaoloBranca
Last active April 8, 2023 04:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GianpaoloBranca/17e5bd6ada9bdb04cca58182db8505d4 to your computer and use it in GitHub Desktop.
Save GianpaoloBranca/17e5bd6ada9bdb04cca58182db8505d4 to your computer and use it in GitHub Desktop.
Copy all components from an Entity to another in Bevy
// Bevy version: 0.10
use bevy::{prelude::*, ecs::system::Command};
// Copy all components from an entity to another.
// Using an entity with no components as the destination creates a copy of the source entity.
// panics if
// - the components are not registered in the type registry,
// - the world does not have a type registry
// - the source or destination entity do not exist
pub fn clone_entity_components(world: &mut World, source: Entity, destination: Entity) {
let wc = world.as_unsafe_world_cell();
unsafe {
let registry = wc.world().get_resource::<AppTypeRegistry>().unwrap();
let type_registry = registry.read();
let entity_ref = wc.world().get_entity(source).unwrap();
let archetype = entity_ref.archetype();
let components = wc.world().components();
for component_id in archetype.components() {
let component_info = components.get_info(component_id).unwrap();
let type_id = component_info.type_id().unwrap();
let registration = type_registry.get(type_id).unwrap();
// here is where the magic happens
let reflect_component = registration.data::<ReflectComponent>().unwrap();
reflect_component.copy(
wc.world_mut(),
wc.world_mut(),
source,
destination
);
}
}
}
// this allows the command to be used in systems
pub struct CloneEntity(pub Entity, pub Entity);
impl Command for CloneEntity {
fn write(self, world: &mut World) {
clone_entity_components(world, self.0, self.1);
}
}
// **********************************************************
// Adapt the code below to your needs
// **********************************************************
// Components must derive Reflect and use reflect(Component)
// If your component includes some other structs, these have to derive from Reflect and FromReflect
#[derive(Component, Reflect, Default)]
#[reflect(Component)]
pub struct Foo {
pub bar: i32,
pub baz: bool,
}
// In your system, clone an entity like this:
fn clone_entity(mut commands: Commands, /* whatever you want that gets your entity */) {
// your code here to fetch the source entity
// ...
let copy = commands.spawn_empty().id();
commands.add(CloneEntity(entity, copy));
}
// Also, remember to register your components in the App Type Registry!
// Some predefined components are already registered (e.g. Name)
// You can write your own plugin where you put all your registrations
{
let registry = app.world.resource_mut::<AppTypeRegistry>();
let mut wr = registry.write();
wr.register::<Foo>();
// other structs...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment