Last active
April 8, 2023 04:52
-
-
Save GianpaoloBranca/17e5bd6ada9bdb04cca58182db8505d4 to your computer and use it in GitHub Desktop.
Copy all components from an Entity to another in Bevy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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