Ejemplo n.º 1
0
        private static void DoGeneratePrefabsIfNecessary(MB3_MeshBakerGrouper grouper, List <MB3_MeshBakerCommon> newBakers)
        {
            if (!grouper.prefabOptions_autoGeneratePrefabs &&
                !grouper.prefabOptions_mergeOutputIntoSinglePrefab)
            {
                return;
            }
            if (!MB_BatchPrefabBakerEditorFunctions.ValidateFolderIsInProject("Output Folder", grouper.prefabOptions_outputFolder))
            {
                return;
            }

            if (grouper.prefabOptions_autoGeneratePrefabs)
            {
                for (int i = 0; i < newBakers.Count; i++)
                {
                    MB3_MeshBakerCommon baker = newBakers[i];

                    string path = grouper.prefabOptions_outputFolder;
                    // To handle paths with a different root
                    //path = MB_BatchPrefabBakerEditorFunctions.ConvertAnyPathToProjectRelativePath(path);

                    // Generate a new prefab name
                    string prefabName = baker.name.Replace("MeshBaker", "CombinedMesh");
                    prefabName = prefabName.Replace(" ", "_");
                    prefabName = prefabName.Replace(",", "_");
                    prefabName = prefabName.Trim(Path.GetInvalidFileNameChars());
                    prefabName = prefabName.Trim(Path.GetInvalidPathChars());

                    string pathName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + prefabName + ".prefab");
                    if (pathName == null || pathName.Length == 0)
                    {
                        Debug.LogError("Could not generate prefab " + prefabName + " in folder " + path + ". There is something wrong with the path or prefab name.");
                        continue;
                    }

                    // Generate a new prefab
                    GameObject go = new GameObject(baker.name);
                    GameObject pf = MBVersionEditor.PrefabUtility_CreatePrefab(pathName, go);

                    // Configure the baker to bake into the prefab
                    baker.resultPrefab = pf;
                    baker.resultPrefabLeaveInstanceInSceneAfterBake = true;
                    baker.meshCombiner.outputOption = MB2_OutputOptions.bakeIntoPrefab;
                    if (grouper.parentSceneObject != null)
                    {
                        baker.parentSceneObject = grouper.parentSceneObject;
                    }

                    MB_Utility.Destroy(go);
                }
            }
        }
        public void SaveMeshesToOutputFolderAndAssignToSMRs(Mesh[] targetMeshes, SkinnedMeshRenderer[] targetSMRs)
        {
            //validate meshes
            for (int i = 0; i < targetMeshes.Length; i++)
            {
                if (targetSMRs[i] == null)
                {
                    Debug.LogError(string.Format("Target Mesh {0} is null", i));
                    return;
                }

                if (targetSMRs[i].sharedMesh == null)
                {
                    Debug.LogError(string.Format("Target Mesh {0} does not have a mesh", i));
                    return;
                }
                MB_PrefabType pt = MBVersionEditor.PrefabUtility_GetPrefabType(targetMeshes[i]);
                if (pt == MB_PrefabType.modelPrefabAsset)
                {
                    Debug.LogError(string.Format("Target Mesh {0} is an imported model prefab. Can't modify these meshes because changes will be overwritten the next time the model is saved or reimported. Try instantiating the prefab and using skinned meshes from the scene instance.", i));
                    return;
                }
            }
            //validate output folder
            if (outputFolderProp.stringValue == null)
            {
                Debug.LogError("Output folder must be set");
                return;
            }
            else
            {
                if (!MB_BatchPrefabBakerEditorFunctions.ValidateFolderIsInProject("Output Folder", outputFolderProp.stringValue))
                {
                    return;
                }
            }
            for (int i = 0; i < targetMeshes.Length; i++)
            {
                Mesh   m   = targetMeshes[i];
                string pth = MB_BatchPrefabBakerEditorFunctions.ConvertAnyPathToProjectRelativePath(outputFolderProp.stringValue + "/" + targetMeshes[i].name + ".Asset");
                if (pth == null)
                {
                    Debug.LogError("The output folder must be a folder in the project Assets folder.");
                    return;
                }
                AssetDatabase.CreateAsset(m, pth);
                targetSMRs[i].sharedMesh = m;
                Debug.Log(string.Format("Created mesh at {0}. Updated Skinned Mesh {1} to use created mesh.", pth, targetSMRs[i].name));
            }
            AssetDatabase.SaveAssets();
        }
        private static void _generateMeshBakers(UnityEngine.Object target)
        {
            MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target;
            MB3_TextureBaker     tb  = tbg.GetComponent <MB3_TextureBaker>();

            if (tb == null)
            {
                Debug.LogError("There must be an MB3_TextureBaker attached to this game object.");
                return;
            }

            if (tb.GetObjectsToCombine().Count == 0)
            {
                Debug.LogError("The MB3_MeshBakerGrouper creates clusters based on the objects to combine in the MB3_TextureBaker component. There were no objects in this list.");
                return;
            }

            if (tbg.parentSceneObject == null ||
                !MB_Utility.IsSceneInstance(tbg.parentSceneObject.gameObject))
            {
                GameObject g = new GameObject("CombinedMeshes-" + tbg.name);
                tbg.parentSceneObject = g.transform;
            }

            //check if any of the objes that will be added to bakers already exist in child bakers
            List <GameObject> objsWeAreGrouping = tb.GetObjectsToCombine();

            MB3_MeshBakerCommon[] alreadyExistBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>();
            bool foundChildBakersWithObjsToCombine   = false;

            for (int i = 0; i < alreadyExistBakers.Length; i++)
            {
                List <GameObject> childOjs2Combine = alreadyExistBakers[i].GetObjectsToCombine();
                for (int j = 0; j < childOjs2Combine.Count; j++)
                {
                    if (childOjs2Combine[j] != null && objsWeAreGrouping.Contains(childOjs2Combine[j]))
                    {
                        foundChildBakersWithObjsToCombine = true;
                        break;
                    }
                }
            }

            bool proceed = true;

            if (foundChildBakersWithObjsToCombine)
            {
                proceed = EditorUtility.DisplayDialog("Replace Previous Generated Bakers", "Delete child bakers?\n\n" +
                                                      "This grouper has child Mesh Baker objects from a previous clustering. Do you want to delete these and create new ones?", "OK", "Cancel");
            }

            if (tbg.prefabOptions_autoGeneratePrefabs)
            {
                if (!MB_BatchPrefabBakerEditorFunctions.ValidateFolderIsInProject("Output Folder", tbg.prefabOptions_outputFolder))
                {
                    Debug.LogError("If " + gc_prefabOptions_autoGeneratePrefabs.text + " is enabled, you must provide an output folder. Prefabs will be saved in this folder.");
                    proceed = false;
                }
            }

            if (proceed)
            {
                if (foundChildBakersWithObjsToCombine)
                {
                    tbg.DeleteAllChildMeshBakers();
                }
                List <MB3_MeshBakerCommon> newBakers = tbg.grouper.DoClustering(tb, tbg);
                if (newBakers.Count > 0)
                {
                    DoGeneratePrefabsIfNecessary(tbg, newBakers);
                }
            }
        }