Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
11
Question by mcroswell · Mar 05, 2010 at 10:41 PM · editorcomponentclonewizard

Editor Wizard: Copy Existing Components to Another GameObject

Since the editor does not have a way to copy the child components of a game object and apply that copy to another game object, I am trying to make a Editor Wizard that will do this.

My wizard is able to copy the components presently, but cannot copy the values of the source.

Any ideas?

Here's what I have so far (below). The commented-out code doesn't work (so, for example, I know that CloneComponent will just make clones in the source - makes a mess so don't use - it will duplicate your transform components, for example - not good!). I left the comments in so folks realize that I've tried the obvious code from the reference and so we don't "reinvent the broken wheel" so to speak.

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 // CopyComponents - by Michael L. Croswell for Colorado Game Coders, LLC
 // March 2010
 
 public class CopyComponents : ScriptableWizard
 {   
     public bool copyValues = true;  
     public GameObject fromObject;
     public GameObject toObject;
     
     [MenuItem ("Custom/Copy Components")]
     static void CreateWizard ()
     {
         ScriptableWizard.DisplayWizard("Copy Components", typeof(CopyComponents), "Copy");  
     }
     
     void OnWizardCreate ()
     {
         //foreach (GameObject go in fromObject.GetFiltered(typeof(GameObject), SelectionMode.TopLevel))
         Component[] fromComps = fromObject.GetComponents(typeof(Component));
         Component[] toComps = toObject.GetComponents(typeof(Component));
         string msg = "";
         msg += "FromObject total components count is " + fromComps.Length;
         msg += "\nToObject total components count is " + toComps.Length;    
         /// Blows up Unity iPhone: EditorUtility.CopySerialized(fromObject, toObject); // Source to Destination 
         /// return;
         int i = 0;
         for (i=0; i < fromComps.Length; i++)
         {
             string t1 = fromComps[i].GetType().Name;
             string t2 = "";
             msg += "\n#" + i + " is type " + t1;
             if (i < toComps.Length)
                 t2 = toComps[i].GetType().Name;
             if (t2 != t1)
             {
                 //if (copyValues)
                 //  toObject.AddComponent(EditorUtility.CloneComponent(fromComps[i]));
                 //else
                 toObject.AddComponent(fromComps[i].GetType());
                 toComps = toObject.GetComponents(typeof(Component));
                 if (i < toComps.Length)
                 {
                     Debug.Log("toComps.Length is " + toComps.Length + " i is " + i);
                     // Not good at all: EditorUtility.CopySerialized(fromComps[i], toComps[i]); // Source to Destination      
                     toComps[i] = fromComps[i];  // Does nothing apparently. 
                     // This doesn't work it just duplicates inside fromObject: EditorUtility.CloneComponent(fromComps[i]);
                     msg += "\t Add To: Increasing toObject component count to " + toComps.Length;
                 }
                 else
                 {
                     msg += "\t Problem: i is " + i + " but toComps is only " + toComps.Length;
                 }
             }
             else
             {
                 if (copyValues)
                 {
                    // Doesn't make a difference: Destroy(toComps[i]);
                     //Duplicates in Source (not good either): toObject.AddComponent(EditorUtility.CloneComponent(fromComps[i]));
                     // Not good: EditorUtility.CopySerialized(fromComps[i], toComps[i]); // Source to Destination      
                    toComps[i] = fromComps[i]; //Does nothing.  
                    // Trouble here also: EditorUtility.CloneComponent(fromComps[i]);
                    msg += "\t Cloned values.";
                 }
             }   
         }
         EditorUtility.DisplayDialog("Game Object Facts",  msg , "OK", "");
     }
 }

Thanks in advance!

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image J3-Gaming · Sep 16, 2011 at 08:11 PM 0
Share

Can you please post your full working script?

3 Replies

· Add your reply
  • Sort: 
avatar image
11
Best Answer

Answer by SimTex · Mar 07, 2010 at 10:08 PM

Use reflection.

Component new_component = gameObject.AddComponent(old_component.GetType());
foreach (FieldInfo f in old_component.GetType().GetFields())
{
  f.SetValue(new_component, f.GetValue(old_component));
}

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Mortoc · Mar 11, 2010 at 06:33 PM 0
Share

This works for about 90% of unity objects, but there's some weird cases that'll bite you (like ParticleEmitters).

avatar image mcroswell · Mar 23, 2010 at 03:00 AM 1
Share

Thank you! I added

using System.Reflection;

and modified your code above to fit my current variables.

Works great!!

avatar image mcroswell · Mar 23, 2010 at 05:36 AM 0
Share

$$anonymous$$otorc: Thanks for the heads=up. I will probably try to put in special-case code for ParticleEmitters. Currently my project doesn't use them, but I am planning on making this general usage and sharing.

avatar image Waz · Jun 19, 2010 at 09:15 PM 0
Share

While I definitely wish you the best, I hope even more that unity gets this basic feature out-of-the-box eventually.

avatar image yoyo · Jan 09, 2011 at 07:11 AM 0
Share

I suspect the "weird cases" actually have C# attribute markup on the fields (and properties?) that you need to consider. Have a look at FieldInfo.GetCustomAttributes (and PropertyInfo.GetCustomAttributes) and see how the Unity devs have marked up those weird cases.

Show more comments
avatar image
13

Answer by Eran-Yaacobi · Dec 28, 2014 at 11:26 PM

A better approach would be to use UnityEditorInternal namespace:

 UnityEditorInternal.ComponentUtility.CopyComponent(componentToCopy);
 UnityEditorInternal.ComponentUtility.PasteComponentAsNew(targetGameObject);

You can also use PasteComponentValues instead of PasteComponentAsNew.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jnt · Aug 24, 2016 at 08:56 AM 0
Share

This is what I've been looking for! Thanks a lot man!

avatar image Bunny83 · Aug 24, 2016 at 09:58 AM 0
Share

Just want to note that those methods are "relatively new". They did not exist back then. They got added when the editor got the copy and paste functions inside the context menu. So now you can simply right click on a component header line and copy / paste a component.

avatar image FinnTess · Jul 26, 2019 at 10:35 PM 0
Share

This the most important thing in this page.... thx so much.

avatar image
2

Answer by DR9885 · Sep 20, 2011 at 03:44 AM

To add to that Reflection suggestion, if you are using private serialized variables, like me, you may want something more like this...

 foreach (FieldInfo info in comp.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.NonPublic))
     if(info.IsPublic || info.GetCustomAttributes(typeof(SerializeField),true).Length != 0);
         info.SetValue(newComponent, info.GetValue(comp));
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image piojo · Feb 08, 2012 at 08:55 AM 0
Share

You wrote NonPublic twice. I think you meant "BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic"

avatar image DAVco · Aug 21, 2014 at 04:00 PM 0
Share

Using this method, I was able to successfully copy components that I'd written in my project, however I am unable to copy Unity built-in components such as BoxCollider - any ideas on how we can improve the function in order to do this?

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Is there a way to detect "On Component Attach" and "On Component Remove"?? 2 Answers

How to make changes to a copied object 1 Answer

Script component in Editor vs. runtime-dependent inheritance 0 Answers

how to disable a script component 1 Answer

How to undo removing components in an editor extension? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges