CopyInspector
Yea I know. It’s been a while. I do have two very good excuses though: 2.6 and Unite ‘09. If you enjoyed those then zip it and read on. If not, I’m really out of ammo and sorry for the delay.
At Unite, I attended the talk by John Grden of infrared5 on the special (free) Unity for flash users day. During this session he complained about wanting to be able to copy his runtime transform changes inside the IDE (he was copying by way of paper notes it seemed). I decided to take up the challenge when he continued with “… but someone is probably going to show me how to do that after this” and after his talk I handed him a custom inspector editor script for solving that specific problem.
Later at the conference I had some time to kill and did a rewrite to expand the script to be general for any component type. I didn’t have the time to hand John that version, but I suppose I’ll just email him a link to this post.
- So anyway – lets talk implementation:
- Add CopyInspector.cs to Assets/Editor.
- Add CopyTransformInspector.cs to Assets/Editor.
- For each other component to be made copy/paste-able:
- Add CopyYourComponentTypeInspector.cs to Assets/Editor.
- Rename it appropriately.
- Rename the class to match the file name.
- Change YourComponentType in “[CustomEditor (typeof (YourComponentType))]” to the type of component you wish to affect.
You’ll notice that CopyTransformInspector has some additional code to it. This is due to the fact that this inspector is rendered non-standard and the code provided just replicates that.

The copy transform inspector
Not really sure why syntax highlighting is not kicking in… Will have a look at that later.
Codes!
CopyInspector.cs
public class CopyInspector : Editor
{
static System.Type m_OriginalType;
static Dictionary <PropertyInfo, object> m_Values;
private List <PropertyInfo> GetProperties (Component component)
{
List <string> ignoredProperties;
List <PropertyInfo> properties;
properties = new List <PropertyInfo> ();
ignoredProperties = new List <string> ();
foreach (PropertyInfo propertyInfo in typeof (Component).GetProperties ())
{
ignoredProperties.Add (propertyInfo.Name);
}
foreach (PropertyInfo propertyInfo in component.GetType ().GetProperties ())
{
if (ignoredProperties.Contains (propertyInfo.Name))
{
continue;
}
properties.Add (propertyInfo);
}
return properties;
}
{
DrawDefaultInspector ();
OnCopyInspectorGUI ();
}
{
bool enabled;
List <PropertyInfo> properties;
Component component;
component = target as Component;
if (component == null)
{
return;
}
GUILayout.Space (10.0f);
Color backgroundColor = GUI.backgroundColor;
GUI.backgroundColor = new Color (0.8f, 0.8f, 0.8f);
GUILayout.BeginVertical ("Toolbar");
GUI.backgroundColor = backgroundColor;
GUILayout.BeginHorizontal ();
GUILayout.Space (10.0f);
GUILayout.Label ("Copied: " + (m_OriginalType != null ? m_OriginalType.Name : "Nothing"), "MiniLabel");
GUILayout.FlexibleSpace ();
if (GUILayout.Button (new GUIContent ("Copy", "Copy component values"), "MiniLabel"))
{
m_OriginalType = target.GetType ();
properties = GetProperties (component);
m_Values = new Dictionary <PropertyInfo, object> ();
foreach (PropertyInfo property in properties)
{
m_Values [property] = property.GetValue (component, null);
}
}
enabled = GUI.enabled;
GUI.enabled = target.GetType () == m_OriginalType;
GUILayout.Space (10.0f);
if (GUILayout.Button (new GUIContent ("Paste", "Paste component values"), "MiniLabel"))
{
properties = GetProperties (component);
foreach (PropertyInfo property in properties)
{
if (!property.CanWrite)
{
continue;
}
property.SetValue (component, m_Values [property], null);
}
}
GUILayout.Space (10.0f);
GUI.enabled = enabled;
GUILayout.EndHorizontal ();
GUILayout.EndVertical ();
GUILayout.Space (-2.0f);
}
}
CopyTransformInspector.cs
[CustomEditor (typeof (Transform))]
public class CopyTransformInspector : CopyInspector
{
{
Transform transform;
Vector3 localPosition, localScale;
Quaternion localRotation;
transform = target as Transform;
localPosition = EditorGUILayout.Vector3Field ("Position", transform.localPosition);
localRotation = Quaternion.Euler (EditorGUILayout.Vector3Field ("Rotation", transform.localRotation.eulerAngles));
localScale = EditorGUILayout.Vector3Field ("Scale", transform.localScale);
if (GUI.changed)
{
transform.localPosition = localPosition;
transform.localRotation = localRotation;
transform.localScale = localScale;
}
OnCopyInspectorGUI ();
}
}
CopyYourComponentTypeInspector.cs
[CustomEditor (typeof (YourComponentType))]
public class CopyYourComponentTypeInspector : CopyInspector{}
Hi Angry Ant,
Many thanks for this script..
but for some reason I cannot use the DrawDefaultInspector() call since it is throwing me a compile error, saying that it does not exist in the current context.
I also changed the ‘override’ keyword to ‘virtual’ in CopyInspector.cs since that also was throwing a compile error.
I have still not migrated onto Unity2.6 and am still using 2.5…
Many thanks,
Akshay
ohh.. and i just noticed.. does the CopyInspector need any more code similar to what CopyTransformInspector has.. I haven’t got to the other components yet since I was still working on getting the transform copying to work..
-Akshay
This script does indeed rely on 2.6 specific API. If you need this to work for other components, read the steps below the “For each other component to be made copy/paste-able” point.
The scripts work. I find – making it possible for multiple items properties to be changed simultaneously – is what I’d want… Nothing to copy paste.
Select n-many Crates for example. Change mass from 1 to 25.
This will hopefully be different in U.3 anyways.
Yayy!! Thanks, that is really nice. Exact what i was looking for!!