public void ConvertThisToNewType(InventoryItemBase currentItem, Type type) { var comp = (InventoryItemBase)currentItem.gameObject.AddComponent(type); ReflectionUtility.CopySerializableValues(currentItem, comp); // Set in database for (int i = 0; i < ItemManager.database.items.Length; i++) { if (ItemManager.database.items[i].ID == currentItem.ID) { ItemManager.database.items[i] = comp; selectedItem = comp; //UnityEngine.Object.DestroyImmediate(((InventoryItemBase)itemEditorInspectorList[i].target).gameObject); //itemEditorInspectorList[i] = null; itemEditorInspector = GetEditor(selectedItem, i); break; } } //selectedItem = comp; //itemEditorInspector = Editor.CreateEditor(selectedItem); //EditorUtility.SetDirty(selectedItem); GUI.changed = true; Object.DestroyImmediate(currentItem, true); // Get rid of the old object window.Repaint(); }
private static void ReplaceOldTypes <T1, T2>(T1[] old, Action <T2[]> callbackNew) where T1 : class, new() where T2 : ScriptableObject { var newArr = new T2[old.Length]; for (int i = 0; i < newArr.Length; i++) { var scriptableObject = ScriptableObjectUtility.CreateAsset <T2>(InventoryScriptableObjectUtility.GetSaveFolderForType(typeof(T2)), DateTime.Now.ToFileTimeUtc() + ".asset", false); ReflectionUtility.CopySerializableValues(old[i], scriptableObject); UnityEditor.EditorUtility.SetDirty(scriptableObject); newArr[i] = scriptableObject; } callbackNew(newArr); }
// TODO: Check if this is working... public override void UpdateIssue() { var types = ReflectionUtility.GetAllClassesWithAttribute(typeof(ReplacedByAttribute), true); foreach (var currentType in types) { var newComponentType = (ReplacedByAttribute)currentType.GetCustomAttributes(typeof(ReplacedByAttribute), true).First(); if (typeof(UnityEngine.Component).IsAssignableFrom(currentType)) { var components = Resources.FindObjectsOfTypeAll(currentType).Cast <UnityEngine.Component>().ToArray(); foreach (var component in components) { try { var tempComponent = component; var tempNewType = newComponentType; issues.Add(new GameRuleIssue("Deprecated type " + tempComponent.GetType() + " is used", MessageType.Error, new GameRuleAction("Fix (replace)", () => { if (tempComponent != null && tempComponent.gameObject != null) { var newComponent = tempComponent.gameObject.AddComponent(tempNewType.type); ReflectionUtility.CopySerializableValues(tempComponent, newComponent); UnityEngine.Object.DestroyImmediate(tempComponent, true); } }), new GameRuleAction("Select object", () => { SelectObject(tempComponent); }))); } catch (Exception) { // Ignored } UnityEditor.EditorUtility.SetDirty(component); } } } }
/// <summary> /// The method implements deep clone using reflection. /// </summary> /// <param name="obj">It is the object used to deep clone.</param> /// <returns>Return the deep clone.</returns> public static object CreateDeepClone(object obj) { if (obj == null) { return(null); } var type = obj.GetType(); // No need to clone simple types if (type.IsPrimitive || type.IsEnum || type == typeof(string)) { return(obj); } // If the type of the object is the Array, we use the CreateInstance method to get // a new instance of the array. We also process recursively this method in the // elements of the original array because the type of the element may be the reference // type. if (type.IsArray) { string typeName = type.AssemblyQualifiedName.Replace("[]", string.Empty); Type typeElement = Type.GetType(typeName); if (typeElement != null) { var array = obj as Array; Array copiedArray = Array.CreateInstance(typeElement, array.Length); for (int i = 0; i < array.Length; i++) { copiedArray.SetValue(CreateDeepClone(array.GetValue(i)), i); } return(copiedArray); } DevdogLogger.Log("Couldn't copy array of type " + typeName); return(obj); } // Scriptable objects should be created and saved in a folder; Use the same folder as source item... if (typeof(ScriptableObject).IsAssignableFrom(type)) { var currentFolder = AssetDatabase.GetAssetPath((UnityEngine.Object)obj); currentFolder = currentFolder.Substring(0, currentFolder.LastIndexOf('/')); // DevdogLogger.Log("Creating deepclone of scriptable object: saving to :: " + currentFolder); if (AssetDatabase.IsValidFolder(currentFolder)) { var copy = ScriptableObjectUtility.CreateAsset(type, currentFolder, DateTime.Now.ToFileTimeUtc() + ".asset"); ReflectionUtility.CopySerializableValues(obj, copy); return(copy); } return(null); } // If the type of the object is class or struct, it may contain the reference fields, // so we use reflection and process recursively this method in the fields of the object // to get the deep clone of the object. // We use Type.IsValueType method here because there is no way to indicate directly whether // the Type is a struct type. if (type.IsClass || type.IsValueType) { // A reference that we actually want to keep if (obj is UnityEngine.Object) { return(obj); } object copiedObject = Activator.CreateInstance(obj.GetType()); // Get all FieldInfo. FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo field in fields) { object fieldValue = field.GetValue(obj); if (fieldValue != null) { // Don't clone unity objects any further, just go with a ref. if (field.FieldType.IsAssignableFrom(typeof(UnityEngine.Object)) || field.FieldType.IsAssignableFrom(typeof(MonoBehaviour))) { field.SetValue(copiedObject, fieldValue); continue; } // Get the deep clone of the field in the original object and assign the // clone to the field in the new object. field.SetValue(copiedObject, CreateDeepClone(fieldValue)); } } return(copiedObject); } throw new ArgumentException("The object is unknown type (" + obj.GetType() + ")"); }