Copy reference from one component to another derived component.,

I have a game object with a script attached to it. I’ve connected all the properties in the editor. Now I’m trying to create a similar object which instead uses a derived class component. I want to copy all the properties that I’ve connected in the base class component to the derived class component.

Is there a way to do this?,

Well, yes, sort of.

  • First copy your original component to your targer object. You can copy and paste components in the inspector through the context menu
  • Once you have the instance you would switch the inspector into Debug mode (top right menu inside the inspector)
  • Now you can replace the script asset in your component to your new derived class by dragging the new script onto the “Script” field.
  • Finally just switch the inspector back to normal.

Now you should have an instance of the new class but the serialized data should still be the same.

At first I thought Unity’s own EditorUtility.CopySerialized(Object obj0, Object obj1) could’ve handled doing such an operation, but that turned out to not be the case, as it only allows copy/pasting on same-type objects (i.e. no polymorphism allowed! :frowning: )

I then remembered some other nifty builtin commands that would allow me to create a tool to achieve what you’re after:

#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
public static class ComponentUtil
{
    static SerializedObject source;
    [MenuItem("CONTEXT/Component/CopySerialized")]
    public static void CopySerializedFromBase(MenuCommand command)
    { source = new SerializedObject(command.context); }

    [MenuItem("CONTEXT/Component/PasteSerialized")]
    public static void PasteSerializedFromBase(MenuCommand command)
    {
        SerializedObject dest = new SerializedObject(command.context);
        SerializedProperty prop_iterator = source.GetIterator();
        //jump into serialized object, this will skip script type so that we dont override the destination component's type
        if (prop_iterator.NextVisible(true))
        {
            while (prop_iterator.NextVisible(true)) //itterate through all serializedProperties
            {
                //try obtaining the property in destination component
                SerializedProperty prop_element = dest.FindProperty(prop_iterator.name); 

                //validate that the properties are present in both components, and that they're the same type
                if (prop_element != null && prop_element.propertyType == prop_iterator.propertyType) 
                {
                    //copy value from source to destination component
                    dest.CopyFromSerializedProperty(prop_iterator); 
                }
            }
        }
        dest.ApplyModifiedProperties();
    }
}
#endif

I find it a bit annoying that this creates another “copy component”-menu item, but I wasn’t able to extract the serializedObject from wherever unity stores the copied component when using the normal “copy component”-menu item. But hey, it works!

(it will also allow you to copy properties onto components that are not of the same base class. which isn’t really intended, but it’s simpler not to add any additional code to prohibit this)

Hope this is useful!