Best practice for copying Components from one GameObject to another?

Hello fellow Unity users. Im writing an Editor Script that should copy all Components from one GameObject to another. Unfortunately I have encountered some problems in doing so.

My first atempt was using the EditorUtility.CopySerialized function:

Foo from = gameObjectFrom.GetComponent<Foo>();
Foo to = gameObjectTo.AddComponentn<Foo>();
EditorUtility.CopySerialized(from, to);

CopySerialized seems to be working. Unfortunatelly later I get the Error ‘Component (Foo) has a broken GameObject reference. Fixing!’

Then I tried using Reflection:

foreach(FieldInfo field in fromComponent.GetType().GetFields())
	field.SetValue(toComponent, field.GetValue(fromComponent));

When I try using this on an Animation Component, it has no fields. Instead the Animation Component has 31 Properties and Im not sure if it’s a good idea to reflection-set all of these properties.

So, is there a good and reliable way to copy Components from one GameObject to another and that will work with all components?

EditorUtility.CopySerialized should work, but if it doesn’t, you can simply use the (undocumented) UnityEditorInternal.ComponentUtility class:

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

This seems to be identical to the actual commands in the component’s context-menu in the inspector, so there shouldn’t be any problems with it.

Unity uses it’s own serializer. Public supported fields as well as private fields (marked with SerializeField) are serialized and saved. You could try to roll your own mechanism to find all the variables that should be serialized, or just use
EditorUtility.CopySerialized which is made for this purpose :wink:

I know this was asked years ago but I’m a bit surprised that no-ones ever actually given the most likely answer.

This may have changed now in Unity 5, but it Unity 4, when using logarithmic rolloff mode, the .maxDistance setting of an AudioSource doesn’t actually determine when the sound volume reaches zero - it actually sets the point where it stops attenuating.

So unlike a linear rolloff, the smaller your maxDistance value is set, the louder your sound will be when far away.

You can fix this by adjusting the curve yourself to go to zero at or just before the maxDistance point. Unfortuntately there’s currently no way to set a custom curve in script.