Hi everyone,
So today, I was working on a (hopefully) short project to create a system that automatically finds differences between two GameObjects. When I ran the code on two planes, though, I found these two logs (having to do with the Materials of the plane):
COMPONENT: UnityEngine.MeshRenderer
VAR: material
ORIGINAL: Default-Material (Instance) (UnityEngine.Material)
NEW: Default-Material (Instance) (UnityEngine.Material)
As you can see, this log is telling me that MeshRender’s material is different in Plane 1 & 2, even though they are the exact same. I also got this log:
COMPONENT: UnityEngine.MeshRenderer
VAR: materials
ORIGINAL: UnityEngine.Material[ ]
NEW: UnityEngine.Material[ ]
Then I added a piece of code that prints out the whole list (if it is one) and got this:
COMPONENT: UnityEngine.MeshRenderer
VAR: materials
ORIGINAL: [Default-Material (Instance) (UnityEngine.Material)]
NEW: [Default-Material (Instance) (UnityEngine.Material)]
I’m pretty sure the reason why this is happening is because of the (Instance) type you can see on the materials. Is there any way (other than a really hacky way by going through a string to find if “(Instance)” is inside it) to detect if the value is an Instance?
My Code:
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System;
using UnityEngine;
public class testsiism : MonoBehaviour
{
public GameObject original;
public GameObject changed;
public class Info
{
public Component myComp { set; private get; }
public PropertyInfo thisVar { set; private get; }
public string objectName { get { return myComp.name; } private set { } }
public Type componentName { get { return myComp.GetType(); } private set { } }
public string varName { get { return thisVar.Name; } private set { } }
public Type type { get { return thisVar.PropertyType; } private set { } }
public object value { get {
try
{
return thisVar.GetValue(myComp, null);
}
catch (Exception e)
{
if (!(e is TargetInvocationException))
{
Debug.LogError(e);
}
return null;
}
} private set { } }
public bool canWrite { get { return thisVar.CanWrite; } private set { } }
}
public List<Info> originalProperties;
public List<Info> changedProperties;
void Start()
{
originalProperties = GetProperties(original);
changedProperties = GetProperties(changed);
// COMPARE TIME!
foreach (Info currentInfo in originalProperties)
{
bool foundComponent = false;
foreach (Info compareInfo in changedProperties)
{
if (currentInfo.componentName == compareInfo.componentName && currentInfo.varName == compareInfo.varName)
{
if (currentInfo.value != null && compareInfo.value != null && currentInfo.canWrite && compareInfo.canWrite && !(currentInfo.value.Equals(compareInfo.value)))
{
// Print out list so I can see what went wrong
try
{
string toPrint = "COMPONENT: " + currentInfo.componentName + " VAR: " + currentInfo.varName + " ORIGINAL: [";
foreach (object obj in (Array)currentInfo.value)
{
if (toPrint.EndsWith("["))
{
toPrint += obj.ToString();
} else
{
toPrint += ", " + obj.ToString();
}
}
toPrint += "] NEW: [";
foreach (object obj in (Array)compareInfo.value)
{
if (toPrint.EndsWith("["))
{
toPrint += obj.ToString();
}
else
{
toPrint += ", " + obj.ToString();
}
}
toPrint += "]";
Debug.Log(toPrint);
} catch
{
Debug.Log("COMPONENT: " + currentInfo.componentName + " VAR: " + currentInfo.varName + " ORIGINAL: " + currentInfo.value + " NEW: " + compareInfo.value);
}
}
foundComponent = true;
break;
}
}
if (!foundComponent)
{
Debug.Log("ADD TO NEW: " + currentInfo.componentName);
}
}
}
List<Info> GetProperties(GameObject input)
{
Component[] myComponents = input.GetComponents(typeof(Component));
List<Info> result = new List<Info>();
foreach (Component myComp in myComponents)
{
Type myObjectType = myComp.GetType();
foreach (PropertyInfo thisVar in myComp.GetType().GetProperties())
{
try
{
if (thisVar.Name.ToString() != "name") // All components have this - we don't need to compare it.
{
Info currentInfo = new Info();
currentInfo.myComp = myComp;
currentInfo.thisVar = thisVar;
result.Add(currentInfo);
}
// For testing purposes - prints out all the data
// Debug.Log("GameObject: " + myComp.name + " Component Name: " + myComp.GetType() + " Var Name: " + thisVar.Name + " Type: " + thisVar.PropertyType + " Value: " + thisVar.GetValue(myComp, null) + "\n");
}
catch (Exception e)
{
if (!(e is TargetInvocationException))
{
Debug.LogError(e);
}
}
}
}
return result;
}
}
(Yes, I know, it’s really messy.)
Thanks! I hope I can fix this soon!