@@ -548,6 +548,105 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
548
548
self
549
549
}
550
550
551
+ /// Clones a [`Bundle`] to a target entity.
552
+ ///
553
+ /// # Example
554
+ ///
555
+ /// ```
556
+ /// # use bevy_ecs::prelude::*;
557
+ /// #
558
+ /// # #[derive(Component, Clone)]
559
+ /// # struct Dummy;
560
+ /// #
561
+ /// # #[derive(Bundle, Clone)]
562
+ /// # struct Characteristics {
563
+ /// # _dummy: Dummy
564
+ /// # }
565
+ /// #
566
+ /// # #[derive(Component)]
567
+ /// # struct Offspring { entity: Entity }
568
+ /// #
569
+ /// fn duplicate(mut commands: Commands, query: Query<(Entity, &Offspring)>) {
570
+ /// for (source, Offspring { entity: target }) in query.iter() {
571
+ /// commands.entity(source).clone_bundle_to::<Characteristics>(*target);
572
+ /// }
573
+ /// }
574
+ /// ```
575
+ pub fn clone_bundle_to < T > ( & mut self , target : Entity ) -> & mut Self
576
+ where
577
+ T : Bundle + Clone ,
578
+ {
579
+ assert ! (
580
+ self . commands. entities. contains( target) ,
581
+ "Attempting to clone from entity {:?} to entity {:?}, which doesn't exist." ,
582
+ self . entity,
583
+ target
584
+ ) ;
585
+ self . commands . add ( CloneBundle :: < T > {
586
+ source : self . entity ,
587
+ target,
588
+ _bundle : PhantomData ,
589
+ } ) ;
590
+ self
591
+ }
592
+
593
+ /// Clones a [`Component`] to a target entity.
594
+ ///
595
+ /// # Example
596
+ ///
597
+ /// ```
598
+ /// # use bevy_ecs::prelude::*;
599
+ /// #
600
+ /// # #[derive(Component, Clone)]
601
+ /// # struct Infected;
602
+ /// #
603
+ /// # #[derive(Component)]
604
+ /// # struct Nearest { entity: Entity }
605
+ /// #
606
+ /// fn contagion(mut commands: Commands, query: Query<(Entity, &Nearest), With<Infected>>) {
607
+ /// for (source, Nearest { entity: target }) in query.iter() {
608
+ /// commands.entity(source).clone_to::<Infected>(*target);
609
+ /// }
610
+ /// }
611
+ /// ```
612
+ pub fn clone_to < C > ( & mut self , target : Entity ) -> & mut Self
613
+ where
614
+ C : Component + Clone ,
615
+ {
616
+ self . clone_bundle_to :: < ( C , ) > ( target)
617
+ }
618
+
619
+ /// Clones a [`Bundle`] from a source entity.
620
+ ///
621
+ /// See [`clone_bundle_to`](EntityCommands::clone_bundle_to).
622
+ pub fn clone_bundle_from < T > ( & mut self , source : Entity ) -> & mut Self
623
+ where
624
+ T : Bundle + Clone ,
625
+ {
626
+ assert ! (
627
+ self . commands. entities. contains( source) ,
628
+ "Attempting to clone from entity {:?} to entity {:?}, which doesn't exist." ,
629
+ source,
630
+ self . entity
631
+ ) ;
632
+ self . commands . add ( CloneBundle :: < T > {
633
+ source,
634
+ target : self . entity ,
635
+ _bundle : PhantomData ,
636
+ } ) ;
637
+ self
638
+ }
639
+
640
+ /// Clones a [`Component`] from a source entity.
641
+ ///
642
+ /// See [`clone_to`](EntityCommands::clone_to)
643
+ pub fn clone_from < C > ( & mut self , source : Entity ) -> & mut Self
644
+ where
645
+ C : Component + Clone ,
646
+ {
647
+ self . clone_bundle_from :: < ( C , ) > ( source)
648
+ }
649
+
551
650
/// Despawns the entity.
552
651
///
553
652
/// See [`World::despawn`] for more details.
@@ -692,6 +791,54 @@ where
692
791
}
693
792
}
694
793
794
+ pub struct CloneBundle < T > {
795
+ pub source : Entity ,
796
+ pub target : Entity ,
797
+ _bundle : PhantomData < T > ,
798
+ }
799
+
800
+ impl < T > CloneBundle < T > {
801
+ /// Creates a new [`CloneBundle`] with given source and target IDs.
802
+ pub fn new ( source : Entity , target : Entity ) -> Self {
803
+ Self {
804
+ source,
805
+ target,
806
+ _bundle : PhantomData ,
807
+ }
808
+ }
809
+ }
810
+
811
+ impl < T > Command for CloneBundle < T >
812
+ where
813
+ T : Bundle + Clone + ' static ,
814
+ {
815
+ fn write ( self , world : & mut World ) {
816
+ let mut source_mut = if let Some ( some) = world. get_entity_mut ( self . source ) {
817
+ some
818
+ } else {
819
+ panic ! ( "Could not clone a bundle (of type `{}`) from entity {:?} because it doesn't exist in this World.\n \
820
+ If this command was added to a newly spawned entity, ensure that you have not despawned that entity within the same stage.\n \
821
+ This may have occurred due to system order ambiguity, or if the spawning system has multiple command buffers", std:: any:: type_name:: <T >( ) , self . source) ;
822
+ } ;
823
+
824
+ let bundle = if let Some ( some) = source_mut. remove_bundle :: < T > ( ) {
825
+ some
826
+ } else {
827
+ return ;
828
+ } ;
829
+ source_mut. insert_bundle ( bundle. clone ( ) ) ;
830
+
831
+ let mut target_mut = if let Some ( some) = world. get_entity_mut ( self . target ) {
832
+ some
833
+ } else {
834
+ panic ! ( "Could not clone a bundle (of type `{}`) into entity {:?} because it doesn't exist in this World.\n \
835
+ If this command was added to a newly spawned entity, ensure that you have not despawned that entity within the same stage.\n \
836
+ This may have occurred due to system order ambiguity, or if the spawning system has multiple command buffers", std:: any:: type_name:: <T >( ) , self . source) ;
837
+ } ;
838
+ target_mut. insert_bundle ( bundle) ;
839
+ }
840
+ }
841
+
695
842
#[ derive( Debug ) ]
696
843
pub struct Insert < T > {
697
844
pub entity : Entity ,
0 commit comments