Пример #1
0
        /// <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));
            }
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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;
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }