- Home /
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?,
Answer by Bunny83 · Aug 03, 2018 at 04:59 PM
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.
Answer by stektpotet · Aug 04, 2018 at 02:08 PM
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! :( )
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!
I am so glad I find this piece of jam! BTW on line 14 put a using in front of it so it'll get disposed.
using SerializedObject dest = new SerializedObject(command.context);
Or the whole using block as Unity still not there :P
Your answer
Follow this Question
Related Questions
An OS design issue: File types associated with their appropriate programs 1 Answer
Help with Missing Monobehaviours and Asset Serialization? 0 Answers
Is it possible to create a custom gettter/setter on SerializedProperty ? 0 Answers
Accessing methods from another script. C# 1 Answer
Set default editor values for public variables in derived classes 0 Answers