Your reflection code makes not much sense which tells me you don’t really understand what you’re doing. A “FileInfo” instance is static metadata information. It has no relation to a particular class instance. It just describes a field of a certain type.
When you use GetValue on that FieldInfo, you have to provide that actual object instance. It should be obvious that the object you pass in has to be an object of that type that the FieldInfo belongs to. What you’re doing is grabbing all public fields of the first “Component” (which is usually the Transform class) and trying to get those field values from your gameobject. That doesn’t make much sense.
First you should break up your “hairy” lines (Kurt quote) since you need the component reference several times and calling GetComponent every time is not only a waste of time but also clutters the code.
Second I’m wondering what you actually want to do. As I said you only grab the first Component on each gameobject and that’s usually the Transform component. The transform component doesn’t even have any fields (since everything is wrapped by properties for build-in Unity components). Maybe you wanted to get a List of all fields of all components on all gameobject in the scene?
If so it should be something like this:
Example
void Start()
{
BindingFlags allInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
GameObject[] Scene = GameObject.FindObjectsOfType<GameObject>();
var sb = new System.Text.StringBuilder();
foreach (GameObject go in Scene)
{
sb.Clear();
sb.Append("GO: ").Append(go.name).AppendLine();
var components = go.GetComponents<Component>();
foreach(var c in components)
{
var cType = c.GetType();
sb.Append(" Comp:").Append(cType.FullName).AppendLine();
sb.Append(" BaseType:").Append(cType.BaseType.FullName).AppendLine();
foreach (FieldInfo fi in cType.GetFields(allInstance))
{
sb.Append(" F: ");
if (fi.IsPrivate)
sb.Append("[private]");
sb.Append(fi.Name).Append("=").Append(fi.GetValue(c)).AppendLine();
}
foreach (PropertyInfo pi in cType.GetProperties(allInstance))
{
sb.Append(" P: ").Append(pi.Name);
if (pi.CanRead)
{
if (pi.GetIndexParameters().Length == 0)
sb.Append("=").Append(pi.GetValue(c));
else
sb.Append(" (indexer with parameters)");
}
else
sb.Append(" (not readable)");
sb.AppendLine();
}
}
Debug.Log(sb.ToString());
}
}
Note: this will create one Debug.Log per gameobject which is better for performance and readability. All components on that gameobject will be listed with all their public and private instance fields as well as all properties. Only simple properties are actually read. Indexers can’t really be read without knowing what to pass to the index parameters ^^. Static fields of the class won’t show up.
Of course you can get more and more into detail. I’ve once made an editor script to examine all members of a class. Though the more information you want to display, the more edge cases you have to consider so your code does not break on those cases. This currently just prints of whatever value the field contains. This could of course break as well or does not provide any insight. If the value is another class you usually just get the class name (default behaviour of ToString) unless that class has overridden the ToString method.