/// <summary> /// Create an instance of type /// Works with values, list, array, scriptableObject, string /// Components are ignored. /// /// The owner MonoBeahviour is used in case of the creation of a ComponentMonoBehaviour for its internal binding. /// </summary> public static object CreateInstance(Type type, UnityEngine.Object owner = null) { if (typeof(GameObject).IsAssignableFrom(type)) { return(null); } else if (typeof(ComponentMonoBehaviour).IsAssignableFrom(type) && owner != null && owner is MonoBehaviour) { ComponentMonoBehaviour component = ((MonoBehaviour)owner).gameObject.AddComponent(type) as ComponentMonoBehaviour; component.Owner = owner as MonoBehaviour; return(component); } else if (typeof(ScriptableComponent).IsAssignableFrom(type) && owner != null && owner is ScriptableObject) { ScriptableComponent component = ScriptableObject.CreateInstance(type) as ScriptableComponent; component.Owner = owner as ScriptableObject; string path = AssetDatabase.GetAssetPath(owner); if (string.IsNullOrEmpty(path)) { return(null); } AssetDatabase.AddObjectToAsset(component, path); return(component); } else if (typeof(Component).IsAssignableFrom(type)) { if (owner is GameObject) { return(((GameObject)owner).AddComponent(type)); } return(null); } else if (typeof(ScriptableObject).IsAssignableFrom(type)) { return(null); } else if (typeof(UnityEngine.Object).IsAssignableFrom(type)) { return(null); } else if (type.IsArray) { return(Array.CreateInstance(type.GetElementType(), 0)); } else if (type == typeof(string)) { return(""); } else { return(Activator.CreateInstance(type, true)); } }
/// <summary> /// Called when the inspector is about to destroy this one. /// Loop in all the internal and destroy sub-components. /// </summary> public void Erase() { foreach (FieldInfo info in GetFields(GetType(), false)) { object value = info.GetValue(this); if (value is ComponentMonoBehaviour) { ComponentMonoBehaviour component = value as ComponentMonoBehaviour; if (component.Owner == Owner) { component.Erase(); } } } DestroyImmediate(this, true); }
private static void Validate(GameObject go) { ComponentMonoBehaviour[] components = go.GetComponents <ComponentMonoBehaviour>(); for (int i = components.Length - 1; i >= 0; i--) { ComponentMonoBehaviour component = components[i]; if (component == null) { return; } tested.Clear(); component.hideFlags = HideFlags.HideInInspector; if (component.Owner == null || !component.Owner || !Referenced(component.Owner, component)) { Debug.Log("Destroying " + component.ToString() + " because it is orphant."); component.Erase(); continue; } } }
private static ComponentMonoBehaviour CopyComponent(GameObject go, MonoBehaviour owner, ComponentMonoBehaviour original) { Type type = original.GetType(); ComponentMonoBehaviour copy = go.AddComponent(original.GetType()) as ComponentMonoBehaviour; foreach (FieldInfo info in GetFields(type, false)) { if (info.IsLiteral) continue; info.SetValue(copy, CopyObject(go, copy, info.GetValue(original))); } copy.Owner = owner; return copy; }
private static object DeepCopy(object data, UnityEngine.Object owner) { if (!pairs.ContainsKey(owner)) { pairs.Add(owner, owner); } if (data == null || (data is UnityEngine.Object && !((UnityEngine.Object)data))) { return(null); } if (pairs.ContainsKey(data)) { return(pairs[data]); } Type type = data.GetType(); object copy = null; if (typeof(ComponentMonoBehaviour).IsAssignableFrom(type)) { MonoBehaviour parent = owner as MonoBehaviour; if (parent == null) { return(data); } ComponentMonoBehaviour component = Clipboard.CreateInstance(type, owner) as ComponentMonoBehaviour; pairs.Add(data, component); IterateObject(data, component, parent); component.Owner = parent; return(component); } else if (typeof(Component).IsAssignableFrom(type) || typeof(GameObject).IsInstanceOfType(type) || type.Namespace == "System") { return(data); } else if (data is AnimationCurve) { AnimationCurve original = data as AnimationCurve; AnimationCurve animationCopy = new AnimationCurve(); animationCopy.keys = original.keys; animationCopy.preWrapMode = original.preWrapMode; animationCopy.postWrapMode = original.postWrapMode; return(animationCopy); } else if (data is string) { return(((string)data).Clone()); } else if (type.IsArray) { copy = Array.CreateInstance(type.GetElementType(), ((Array)data).Length); for (int i = 0; i < ((Array)data).Length; i++) { ((Array)copy).SetValue(DeepCopy(((Array)data).GetValue(i), owner), i); } } else if (typeof(IList).IsAssignableFrom(type)) { copy = CreateInstance(type); foreach (object o in ((IList)data)) { ((IList)copy).Add(DeepCopy(o, owner)); } } else if (typeof(IDictionary).IsAssignableFrom(type)) { copy = CreateInstance(type); foreach (DictionaryEntry entry in ((IDictionary)data)) { ((IDictionary)copy).Add(DeepCopy(entry.Key, owner), DeepCopy(entry.Value, owner)); } } else if (typeof(UnityEngine.Object).IsAssignableFrom(type)) { copy = (UnityEngine.Object)CreateInstance(type); if (copy == null) { return(data); } EditorUtility.CopySerialized((UnityEngine.Object)data, (UnityEngine.Object)copy); } else { copy = CreateInstance(type); pairs.Add(data, copy); IterateObject(data, copy, owner); } return(copy); }
private static bool Referenced(object owner, ComponentMonoBehaviour target) { if (owner == null || tested.Contains(owner)) { return(false); } else { tested.Add(owner); } Type type = owner.GetType(); foreach (FieldInfo info in Clipboard.GetFields(type)) { if (typeof(UnityEngine.Object).IsAssignableFrom(info.FieldType) && !info.FieldType.IsAssignableFrom(target.GetType())) { continue; } object value = info.GetValue(owner); if (typeof(IList).IsAssignableFrom(info.FieldType)) { IList list = value as IList; if (list != null) { foreach (object item in list) { if (ReferenceEquals(item, target)) { return(true); } if (item != null && item.GetType().IsClass&& Referenced(item, target)) { return(true); } } } } else if (typeof(IDictionary).IsAssignableFrom(info.FieldType)) { IDictionary dictionary = value as IDictionary; if (dictionary != null) { foreach (DictionaryEntry entry in dictionary) { if (ReferenceEquals(entry.Key, target)) { return(true); } if (ReferenceEquals(entry.Value, target)) { return(true); } if (entry.Key != null && entry.Key.GetType().IsClass&& Referenced(entry.Key, target)) { return(true); } if (entry.Value != null && entry.Value.GetType().IsClass&& Referenced(entry.Value, target)) { return(true); } } } } else if (info.FieldType.Namespace == "System" || info.FieldType.Namespace == "UnityEngine") { continue; } else if (info.FieldType.IsAssignableFrom(target.GetType())) { if (ReferenceEquals(value, target)) { return(true); } } else if (info.FieldType.IsClass && Referenced(value, target)) { return(true); } } return(false); }