Exemple #1
0
    private static bool findExistingPrefab(string modelPath, PrefabLabSettings settings, out string foundPrefabPath)
    {
        foundPrefabPath = null;

        string relativeSubdir = modelPath.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1);

        relativeSubdir = relativeSubdir.Remove(relativeSubdir.LastIndexOf("/") + 1);
        string relativeDestinationFolder = settings.DestinationFolder + "/" + relativeSubdir;
        string modelName = Path.GetFileNameWithoutExtension(modelPath);

        //find filepath
        DirectoryInfo di = new DirectoryInfo(Application.dataPath + "/" + relativeDestinationFolder);

        if (di.Exists)
        {
            foreach (FileInfo fi in di.GetFiles())
            {
                if (Path.GetFileNameWithoutExtension(fi.Name) == modelName + settings.PrefabSuffix)
                {
                    foundPrefabPath = relativeDestinationFolder + fi.Name;
                    return(true);
                }
            }
        }

        return(false);
    }
Exemple #2
0
    public static void UpdatePrefabs(Object[] objects, PrefabLabSettings settings)
    {
        for (int i = 0; i < objects.Length; i++)
        {
            string assetPath = AssetDatabase.GetAssetPath(objects[i].GetInstanceID());

            if (assetPath.IndexOf("Assets/" + settings.DestinationFolder) != -1)
            {
                if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.Prefab)
                {
                    string modelPath;
                    if (findExistingModel(assetPath, settings, out modelPath))
                    {
                        UpdatePrefab("Assets/" + modelPath, settings);
                    }
                }
            }

            if (assetPath.IndexOf("Assets/" + settings.SourceFolder) != -1)
            {
                if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.ModelPrefab)
                {
                    UpdatePrefab(assetPath, settings);
                }
            }
        }
    }
Exemple #3
0
    public static Object[] GetModelsOrPrefabs(Object[] objects, PrefabLabSettings settings)
    {
        List <Object> newObjects = new List <Object>();

        for (int i = 0; i < objects.Length; i++)
        {
            string assetPath = AssetDatabase.GetAssetPath(objects[i].GetInstanceID());

            if (assetPath.IndexOf("Assets/" + settings.DestinationFolder) != -1)
            {
                if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.Prefab)
                {
                    string modelPath;
                    if (findExistingModel(assetPath, settings, out modelPath))
                    {
                        newObjects.Add(AssetDatabase.LoadMainAssetAtPath("Assets/" + modelPath));
                    }
                }
            }

            if (assetPath.IndexOf("Assets/" + settings.SourceFolder) != -1)
            {
                if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.ModelPrefab)
                {
                    string prefabPath;
                    if (findExistingPrefab(assetPath, settings, out prefabPath))
                    {
                        newObjects.Add(AssetDatabase.LoadMainAssetAtPath("Assets/" + prefabPath));
                    }
                }
            }
        }

        return(newObjects.Count == 0 ? null : newObjects.ToArray());
    }
    public override void OnInspectorGUI()
    {
        PrefabLabData PLD = target as PrefabLabData;

        if (PLD.Type == PrefabLabObjectType.Old)
        {
            EditorGUILayout.Space();
            EditorGUILayout.HelpBox("This is an old prefab. Please update the prefab to see new features", MessageType.Info, true);
        }
        else if (PLD.Type == PrefabLabObjectType.Root)
        {
            EditorGUILayout.Space();

            PLD.ImportAnimationsAutomatically = EditorGUILayout.Toggle("Import Animations", PLD.ImportAnimationsAutomatically, EditorStyles.toggle);

            EditorGUILayout.Space();

            if (PLD.SkinnedMeshes)
            {
                EditorGUILayout.HelpBox("SkinnedMeshRenderers are not supported yet. To update a skinned mesh correctly select the skinned GameObject and follow instructions. TIP: Try to avoid adding components and GameObjects to the skinned object and it's bones.", MessageType.Warning, true);
            }
        }
        else if (PLD.Type == PrefabLabObjectType.SkinnedMesh)
        {
            EditorGUILayout.Space();
            EditorGUILayout.HelpBox("SkinnedMeshRenderers are not supported yet. To update a skinned mesh correctly you have to delete this gameObject, and all the bones used by this component. Apply the Prefab and update the prefab", MessageType.Warning, true);
        }

        EditorGUILayout.Space();

        if (GUILayout.Button("Update Prefab"))
        {
            string path = AssetDatabase.GetAssetPath(PrefabUpdater.GetInstanceIDOfSceneAndProjectObject(PLD.gameObject));

            PrefabLabSettings settings = PrefabUpdater.GetPrefabLabSettings();

            PrefabUpdater.UpdatePrefab(settings, path);
        }

        if (GUILayout.Button("Select Model"))
        {
            PrefabLabSettings settings = PrefabUpdater.GetPrefabLabSettings();

            Object[] newSelection = PrefabUpdater.GetModelsOrPrefabs(
                new Object[] { AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(PrefabUpdater.GetInstanceIDOfSceneAndProjectObject(PLD.gameObject)), typeof(Object)) }, settings);

            if (newSelection != null)
            {
                Selection.objects = newSelection;
            }
            else
            {
                Debug.Log("There was no prefab lab object found");
            }
        }

        EditorGUILayout.Space();
    }
Exemple #5
0
    public static void UpdatePrefab(PrefabLabSettings settings, string prefabPath)
    {
        string modelPath;

        if (findExistingModel(prefabPath, settings, out modelPath))
        {
            UpdatePrefab("Assets/" + modelPath, settings);
        }
    }
Exemple #6
0
    private static void deletePrefab(string assetPath, PrefabLabSettings settings)
    {
        string prefabPath;

        if (findExistingPrefab(assetPath, settings, out prefabPath))
        {
            AssetDatabase.DeleteAsset("Assets/" + prefabPath);
        }
    }
Exemple #7
0
    public static PrefabLabSettings GetPrefabLabSettings()
    {
        //Read PrefabUpdater settings
        PrefabLabSettings settings = PrefabLabSettings.Defaults;

        if (File.Exists(PrefabLabSettings.Filepath))
        {
            settings.ReadSettingsFromDisk();
        }
        return(settings);
    }
Exemple #8
0
    public override int GetPostprocessOrder()
    {
        //Read PrefabUpdater settings
        PrefabLabSettings settings = PrefabLabSettings.Defaults;

        if (File.Exists(PrefabLabSettings.Filepath))
        {
            settings.ReadSettingsFromDisk();
        }

        return(settings.PostProcessOrder);
    }
Exemple #9
0
    public static void UpdatePrefab()
    {
        //Read PrefabUpdater settings
        PrefabLabSettings settings = PrefabLabSettings.Defaults;

        if (File.Exists(PrefabLabSettings.Filepath))
        {
            settings.ReadSettingsFromDisk();
        }

        PrefabUpdater.UpdatePrefabs(Selection.objects, settings);
    }
Exemple #10
0
    public static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        //Read PrefabUpdater settings
        PrefabLabSettings settings = PrefabLabSettings.Defaults;

        if (File.Exists(PrefabLabSettings.Filepath))
        {
            settings.ReadSettingsFromDisk();
        }

        //Move assets

        List <string> filteredMovedFromAssets;
        List <string> filteredMoveAssets = filterAssets(movedAssets, settings.SourceFolder, PrefabType.ModelPrefab, movedFromAssetPaths, out filteredMovedFromAssets);

        for (int i = 0; i < filteredMoveAssets.Count; i++)
        {
            moveAndRenameAsset(filteredMoveAssets[i], filteredMovedFromAssets[i], settings);
        }

        //Delete assets
        List <string> filteredDeletedAssets = filterAssets(deletedAssets, settings.SourceFolder);

        foreach (string asset in filteredDeletedAssets)
        {
            deletePrefab(asset, settings);
        }

        //Import assets
        List <string> filteredImportAssets = filterAssets(importedAssets, settings.SourceFolder, PrefabType.ModelPrefab);

        foreach (string asset in filteredImportAssets)
        {
            UpdatePrefab(asset, settings);
        }



        //Debug

        /*foreach (string str in importedAssets)
         *  Debug.Log("Reimported Asset: " + str);
         *
         * foreach (string str in deletedAssets)
         *  Debug.Log("Deleted Asset: " + str);
         *
         * for (int i = 0; i < movedAssets.Length; i++)
         *  Debug.Log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]);*/
    }
Exemple #11
0
    //Rename MetaData.Data from NewModelNameSuffix to CurrentModelNameSuffix
    //(New and Current exist so we can detect whether an gameobject has just been imported or its an older part of the prefab)
    private static void RenameNewToCurrent(GameObject root, PrefabLabSettings settings)
    {
        PrefabLabData metadata = root.GetComponent <PrefabLabData>();

        if (metadata != null)
        {
            if (metadata.Data == NewModelNameSuffix)
            {
                metadata.Data = settings.ModelMetadata;
            }
        }

        for (int i = 0; i < root.transform.childCount; i++)
        {
            RenameNewToCurrent(root.transform.GetChild(i).gameObject, settings);
        }
    }
Exemple #12
0
    public static void ShowWindow()
    {
        if (File.Exists(PrefabLabSettings.Filepath))
        {
            settings.ReadSettingsFromDisk();
        }
        else
        {
            settings = PrefabLabSettings.Defaults;
        }

        EditorWindow window = EditorWindow.GetWindow(typeof(PrefabLabWindow), true);

        Rect windowRect = new Rect(200, 300, 320, 460);

        window.position = windowRect;
        window.title    = "Merlin's Prefab Lab";
    }
Exemple #13
0
    public static void SelectPrefabOrModel()
    {
        //Read PrefabUpdater settings
        PrefabLabSettings settings = PrefabLabSettings.Defaults;

        if (File.Exists(PrefabLabSettings.Filepath))
        {
            settings.ReadSettingsFromDisk();
        }

        Object[] newSelection = PrefabUpdater.GetModelsOrPrefabs(Selection.objects, settings);

        if (newSelection != null)
        {
            Selection.objects = newSelection;
        }
        else
        {
            Debug.Log("There was no prefab lab object found");
        }
    }
Exemple #14
0
    private static void moveAndRenameAsset(string movedAsset, string movedFromAssetPath, PrefabLabSettings settings)
    {
        //Substract subdirs from imported asset
        string oldRelativeSubdir = movedFromAssetPath.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1);

        oldRelativeSubdir = oldRelativeSubdir.Remove(oldRelativeSubdir.LastIndexOf("/") + 1);
        string oldRelativeDestinationFolder = settings.DestinationFolder + "/" + oldRelativeSubdir;

        string oldAssetName = Path.GetFileNameWithoutExtension(movedFromAssetPath);
        string oldAssetPath;

        if (findExistingPrefab(oldAssetName, oldRelativeDestinationFolder, settings.PrefabSuffix, out oldAssetPath))
        {
            string relativeSubdir = movedAsset.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1);
            relativeSubdir = relativeSubdir.Remove(relativeSubdir.LastIndexOf("/") + 1);
            string relativeDestinationFolder = settings.DestinationFolder + "/" + relativeSubdir;
            string absoluteSubdir            = Application.dataPath + "/" + relativeDestinationFolder;

            string newAssetName = Path.GetFileNameWithoutExtension(movedAsset);
            string newAssetPath = "Assets/" + relativeDestinationFolder + newAssetName + settings.PrefabSuffix + ".prefab";
            oldAssetPath = "Assets/" + oldAssetPath;

            Directory.CreateDirectory(absoluteSubdir);

            AssetDatabase.MoveAsset(oldAssetPath, newAssetPath);

            Debug.Log("From: " + oldAssetPath + " To: " + newAssetPath + " absoluteSubdir: " + absoluteSubdir);

            if (oldAssetName != newAssetName)
            {
                GameObject GO = (GameObject)AssetDatabase.LoadAssetAtPath(newAssetPath, typeof(GameObject));
                GetChildByName(oldAssetName, GO).name = newAssetName;
            }
        }
    }
Exemple #15
0
    public static void UpdatePrefab(string modelPath, PrefabLabSettings settings)
    {
        //Substract subdirs from imported asset
        string relativeSubdir = modelPath.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1);

        relativeSubdir = relativeSubdir.Remove(relativeSubdir.LastIndexOf("/") + 1);
        string relativeSourceFolder = settings.DestinationFolder + "/" + relativeSubdir;
        string absoluteSubdir       = Application.dataPath + "/" + relativeSourceFolder;

        //Prepare the imported model for modification
        GameObject importedModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(modelPath, typeof(GameObject)));

        AddMetaData(importedModel);

        GameObject lostObjects = null;

        Object originalPrefab;

        if (!FindExistingPrefab(importedModel.name, relativeSourceFolder, settings.PrefabSuffix, out originalPrefab))
        {
            //Create subdirs
            Directory.CreateDirectory(absoluteSubdir);

            AssetDatabase.Refresh();

            //Prefab not found, create one for me please!
            string prefabFilepath = "Assets/" + relativeSourceFolder + importedModel.name + settings.PrefabSuffix + ".prefab";
            Object emptyPrefab    = PrefabUtility.CreateEmptyPrefab(prefabFilepath);
            AssetDatabase.ImportAsset(prefabFilepath);

            //Creating an empty prefab is really empty so we need a gameobject to start with, called parent
            GameObject    parent = new GameObject(importedModel.name + settings.PrefabSuffix);
            PrefabLabData PLD    = parent.AddComponent <PrefabLabData>();
            PLD.Type = PrefabLabObjectType.Root;

            //Mark as max model
            UpdateMetaDataRecursively(importedModel, settings.ModelMetadata, PLD);
            //Copy newModel to prefab
            importedModel.transform.parent = parent.transform;

            originalPrefab = PrefabUtility.ReplacePrefab(parent, emptyPrefab, ReplacePrefabOptions.ReplaceNameBased);

            //Clean up
            GameObject.DestroyImmediate(parent);
        }
        else
        {
            GameObject prefab = (GameObject)GameObject.Instantiate(originalPrefab);
            prefab.name = originalPrefab.name;

            PrefabLabData PLD = prefab.GetComponent <PrefabLabData>();
            if (PLD == null)
            {
                PLD      = prefab.AddComponent <PrefabLabData>();
                PLD.Type = PrefabLabObjectType.Root;
            }

            //Find LostObjects root or create it
            lostObjects = GetChildByName(lostObjectsName, prefab);

            if (lostObjects == null)
            {
                lostObjects = new GameObject(lostObjectsName);
                lostObjects.transform.parent = prefab.transform;
            }

            //Find newModel root in merlin's prefab and do magic
            GameObject prefabModelRoot = GetChildByName(importedModel.name, prefab);

            if (prefabModelRoot != null)
            {
                //Check if object changed from one object to multiple
                if ((prefabModelRoot.transform.GetChildCount() == 0 && importedModel.transform.GetChildCount() != 0) || (prefabModelRoot.transform.GetChildCount() != 0 && importedModel.transform.GetChildCount() == 0))
                {
                    prefabModelRoot.transform.parent = lostObjects.transform;

#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6
                    prefabModelRoot.SetActiveRecursively(false);
#else
                    prefabModelRoot.SetActive(false);
#endif
                    prefabModelRoot = null;

                    Debug.LogWarning("Unity treats model files with one object differently than files with multiple objects. You changed in the number of objects in " + importedModel.name + ". We recovered the old gameobjects in LostObjects.");
                }
            }

            if (prefabModelRoot == null)
            {
                UpdateMetaDataRecursively(importedModel, settings.ModelMetadata, PLD);

                importedModel.transform.parent        = prefab.transform;
                importedModel.transform.localPosition = Vector3.zero;
            }
            else
            {
                //Mark the newly imported as new to know later on if a modelpart has just been imported or its an old prefabpart
                UpdateMetaDataRecursively(importedModel, NewModelNameSuffix, PLD);

                //Does all the magic to childs
                RebuildPrefab(importedModel, prefabModelRoot, modelPath, PLD);
                RescueAndRemove(importedModel, prefabModelRoot, lostObjects);
                RenameNewToCurrent(prefabModelRoot.gameObject, settings);

                //Don't forget the parent
                CopyComponents(importedModel, prefabModelRoot, modelPath, PLD);
            }

            //Clean up if no lostobjects have been found
            if (lostObjects.transform.childCount > 0)
            {
#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6
                lostObjects.SetActiveRecursively(false);
#else
                lostObjects.SetActive(false);
#endif

                Debug.Log("Prefab Lab Warning: There are " + lostObjects.transform.childCount + " objects found which don't have a parent anymore because it has been deleted in the model." +
                          System.Environment.NewLine +
                          "To recover these objects, browse to the gameobject \"" + lostObjectsName + "\" in the prefab " + prefab.name + ".", originalPrefab);
            }
            else
            {
                GameObject.DestroyImmediate(lostObjects);
            }

            //Save created or modified prefab
            PrefabUtility.ReplacePrefab(prefab, originalPrefab, ReplacePrefabOptions.ReplaceNameBased);

            //Clean up
            GameObject.DestroyImmediate(importedModel);
            GameObject.DestroyImmediate(prefab);
        }
    }