EditorGUILayout.ObjectField in c# or GetFields() in java

My problem is that, i’m trying to write a script that copyes every component of every children in an object hierarchy, into an other hierarchy. (mostly, for ragdolls)
If you know a script like this already, please tell me :slight_smile:

oor, in javascript, my issue is this:

var copyComps:Component[] = src.GetComponents(typeof(Component));
	for (var srcComponent:Component in copyComps){
		if (srcComponent.GetType()!=Transform){
			var new_component:Component = dst.gameObject.AddComponent(srcComponent.GetType());
			for(var f: FieldInfo in srcComponent.GetType().GetFields())
			{
				f.SetValue(new_component, f.GetValue(srcComponent));
				Debug.Log(srcComponent.GetType());
			}
			Debug.Log(typeof(srcComponent));
		}
	}

if srcComponent.GetType() is not a script, then the “for(var f: FieldInfo in srcComponent.GetType().GetFields())” cycle is empty. so the srcComponent.GetType().GetFields() is empty.

if it is a script, it works good.

because the idea of getFields came from a c# example, i tried to convert it to c#. But i have an other issue there, in the beginning:

there is a
public GameObject fromTrans;

and in the void OnGUI(), there is a:
fromTrans = EditorGUILayout.ObjectField("From: ",fromTrans,GameObject);

it says: “Expression denotes a type', where a variable’, value' or method group’ was expected”

here r the full scripts:

import System.Reflection;

class CopyComponents extends EditorWindow {
private var fromTrans:Transform;
private var toTrans:Transform;
var anims = false;

private var errorMsg:String;

@MenuItem ("Component/Custom/Copy components")
static function Init () {
	var window : CopyComponents = EditorWindow.GetWindow (CopyComponents);
	window.Show ();
}

function OnGUI () {
	EditorGUILayout.Space();
	EditorGUILayout.Space();
	fromTrans = EditorGUILayout.ObjectField("From: ",fromTrans,Transform);
	toTrans = EditorGUILayout.ObjectField("To: ",toTrans,Transform);
	EditorGUILayout.Space();
	anims = EditorGUILayout.Toggle ("With animations", anims);
	EditorGUILayout.Space();
	EditorGUILayout.Space();
	if (!fromTrans)
		GUILayout.Label ("\"From\" not yet set!", EditorStyles.boldLabel);
	if (!toTrans)
		GUILayout.Label ("\"To\" not yet set!", EditorStyles.boldLabel);
	errorMsg="";
	if (fromTrans&toTrans){
		if (!checkChildrenRecurse(fromTrans,toTrans,"")){
			GUILayout.Label ("Warning: ", EditorStyles.boldLabel);
		}
		if (errorMsg!=""){
			GUILayout.Label(errorMsg);
		}
		EditorGUILayout.BeginHorizontal ();
		EditorGUILayout.Space();
		if (GUILayout.Button ("Copy!")){
			copyComponentsRecurse(fromTrans,toTrans);
		}
		EditorGUILayout.Space();
		EditorGUILayout.EndHorizontal ();
	}
}
}

function copyComponentsRecurse (src : Transform,  dst : Transform)
{
	var toComps:Component[] = dst.GetComponents(typeof(Component));
	for (var dstComponent:Component in toComps){
		if (dstComponent.GetType()!=Transform)
			DestroyImmediate(dstComponent);
	}
	
	var copyComps:Component[] = src.GetComponents(typeof(Component));
	for (var srcComponent:Component in copyComps){
		if (srcComponent.GetType()!=Transform){
			var new_component:Component = dst.gameObject.AddComponent(srcComponent.GetType());
			for(var f: FieldInfo in srcComponent.GetType().GetFields())
			{
				f.SetValue(new_component, f.GetValue(srcComponent));
				Debug.Log(srcComponent.GetType());
			}
			Debug.Log(typeof(srcComponent));
		}
	}
	
	/*var copyComps:Component[] = src.GetComponents(typeof(Component));
	for (var srcComponent:Component in copyComps){
		if (srcComponent.GetType()==Collider)
			Debug.Log(srcComponent.GetType());
		if (srcComponent.GetType()!=Transform){
			var new_component:Component = dst.gameObject.AddComponent(srcComponent.GetType());
			for (var f:System.Reflection.FieldInfo in srcComponent.GetType().GetFields())
			{
				f.SetValue(new_component, f.GetValue(srcComponent));
			}
		}
	}*/
	
	for (var child : Transform in src) {
		var curDst : Transform = dst.Find(child.name);
		if (curDst){
			copyComponentsRecurse(child, curDst);
		}
	}
}

function checkChildrenRecurse (src : Transform,  dst : Transform, srcPath:String) : boolean
{
	if (src.childCount!=dst.childCount){
		errorMsg="Child count of "+srcPath+src.gameObject.name+" in \"From\" is not equal to "+dst.gameObject.name+" in \"To\".\n";
		return false;
	}
	else if (src.childCount>0)
	{
		var okay:boolean=true;
		for (var child : Transform in src) {
			var curDst : Transform = dst.Find(child.name);
			if (curDst){
				if (!checkChildrenRecurse(child, curDst, srcPath+child.gameObject.name+"\\"))
				{
					okay=false;
				}
			}
			else{
				errorMsg="Can't find "+src.gameObject.name+"\\"+srcPath+child.gameObject.name+" in \"To\"\n";
				return false;
			}
		}
		return okay;
	}
	else{
		return true;
	}
}

and the c#:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Reflection;

public class CopyComponentsCSharp : ScriptableWizard {

    public GameObject fromTrans;
    public GameObject toTrans;
	public bool anims = false;  
//	private string errorMsg="";

	[MenuItem ("Component/Custom/Copy ComponentsC#")]

	static void Init () {
	// Get existing open window or if none, make a new one:
	CopyComponentsCSharp window = (CopyComponentsCSharp)EditorWindow.GetWindow (typeof (CopyComponentsCSharp));
	window.Show ();
	}

	void OnGUI()
	{
		EditorGUILayout.Space();
		EditorGUILayout.Space();
		fromTrans = EditorGUILayout.ObjectField("From: ",fromTrans,GameObject) ;
		toTrans = EditorGUILayout.ObjectField("To: ",toTrans,GameObject)  as GameObject;
		EditorGUILayout.Space();
		anims = EditorGUILayout.Toggle ("With animations", anims);
		EditorGUILayout.Space();
		EditorGUILayout.Space();
		if (!fromTrans)
			GUILayout.Label ("\"From\" not yet set!", EditorStyles.boldLabel);
		if (!toTrans)
			GUILayout.Label ("\"To\" not yet set!", EditorStyles.boldLabel);
	}
}

by the way, this is the forum where i saw that this should work:

http://answers.unity3d.com/questions/5242/editor-wizard-copy-existing-components-to-another-gameobject

and a little update: i used the code from this link, and i managed to try fieldinfo out in c#. But it was the same as in javascript: it didnt copied the values.

and in the meantime, i found out why the c# problem occured:
fromTrans = (GameObject)EditorGUILayout.ObjectField("From: ",fromTrans,typeof(GameObject));

instead of fromTrans = EditorGUILayout.ObjectField("From: ",fromTrans,GameObject);

here is the code i made from the code in the link:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Reflection;
// 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 ()
{
    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;    
    int i = 0;
    for (i=0; i<fromComps.Length; i++)
    {
		if (fromComps[i].GetType()!=typeof(Transform)){
                Component new_component = toObject.AddComponent(fromComps[i].GetType());
				foreach (FieldInfo f in fromComps[i].GetType().GetFields())
				{
					f.SetValue(new_component, f.GetValue(fromComps[i]));
				}
		}
    }

    EditorUtility.DisplayDialog("Game Object Facts",  msg , "OK", "");
}
}

so the problem is still: it only works with scripts, but not colliders, meshes.