public override void OnInspectorGUI()
        {
            serializedObject.Update();
            MB3_BoneWeightCopier bwc = (MB3_BoneWeightCopier)target;


            EditorGUILayout.HelpBox("== BETA (please report problems) ==\n\n" +
                                    "This tool helps create skinned mesh parts that can be mix and matched to customize characters. " +
                                    "It adjusts the boneWeights, positions, normals and tangents at the joins to have the same values so there are no tears." +
                                    "\n\n" +
                                    "1) Model the skinned meshes and attach them all to the same rig. The rig may have multiple arms, hands, hair etc...\n" +
                                    "2) At every seam (eg. between an arm mesh and hand mesh) there must be a set of vertices duplicated in both meshes.\n" +
                                    "3) Create one additional mesh that contains another copy of all the geometry. This will be called the Seam Mesh\n" +
                                    "4) Attach it to the rig and adjust the bone weights. This will be the master set of bone weights that will be copied to all the other skinned meshes.\n" +
                                    "5) Mark the seam vertices using the UV channel.\n" +
                                    "    verts with UV > (.5,.5) are seam verts\n" +
                                    "    verts with UV < (.5,.5) are ignored\n" +
                                    "6) Import the model into Unity and create an instance of it in the scene\n" +
                                    "7) Assign the Seam Mesh to the Seam Mesh field\n" +
                                    "8) Assign the parent game object of all the skinned meshes to the Input Game Object field\n" +
                                    "9) Adjust the radius\n" +
                                    "10) Choose an output folder and save the meshes\n" +
                                    "11) Click 'Copy Bone Weights From Seam Mesh'\n", MessageType.Info);

            EditorGUILayout.PropertyField(radiusProp, gc_radius);
            EditorGUILayout.PropertyField(seamMeshProp, gc_seamMesh);
            EditorGUILayout.PropertyField(inputGameObjectProp, gc_inputGameObject);
            EditorGUILayout.PropertyField(outputPrefabProp, gc_outputPrefab);
            //if (GUILayout.Button("Get Skinned Meshes From Input Game Object")) {
            //	GetSkinnedMeshesFromGameObject(bwc);
            //}
            //EditorGUILayout.PropertyField(targetMeshesProp,true);

            if (GUILayout.Button("Copy Bone Weights From Seam Mesh"))
            {
                CopyBoneWeightsFromSeamMeshToOtherMeshes(bwc);
            }
            EditorGUILayout.Separator();
            EditorGUILayout.Separator();
            EditorGUILayout.LabelField("Save Meshes To Project Folder", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(outputFolderProp, gc_outputFolder);
            if (GUILayout.Button("Browse"))
            {
                string path = EditorUtility.OpenFolderPanel("Browse For Output Folder", "", "");
                path = MB_BatchPrefabBakerEditorFunctions.ConvertFullPathToProjectRelativePath(path);
                outputFolderProp.stringValue = path;
            }
            EditorGUILayout.EndHorizontal();
            if (GUILayout.Button("Set Output Folder To Output Prefab Folder"))
            {
                string path = AssetDatabase.GetAssetPath(bwc.outputPrefab);
                path = new System.IO.FileInfo(path).Directory.FullName.Replace('\\', '/');
                path = MB_BatchPrefabBakerEditorFunctions.ConvertFullPathToProjectRelativePath(path);
                outputFolderProp.stringValue = path;
            }
            serializedObject.ApplyModifiedProperties();
        }
        public void DrawGrouperInspector()
        {
            EditorGUILayout.HelpBox("This component helps you group meshes that are close together so they can be combined together." +
                                    " It generates multiple MB3_MeshBaker objects from the List Of Objects to be combined in the MB3_TextureBaker component." +
                                    " Objects that are close together will be grouped together and added to a new child MB3_MeshBaker object.\n\n" +
                                    " TIP: Try the new agglomerative cluster type. It's awsome!", MessageType.Info);
            MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target;

            MB3_TextureBaker tb = tbg.GetComponent <MB3_TextureBaker>();

            Transform pgo = (Transform)EditorGUILayout.ObjectField(gc_ParentSceneObject, parentSceneObject.objectReferenceValue, typeof(Transform), true);

            if (pgo != null && MB_Utility.IsSceneInstance(pgo.gameObject))
            {
                parentSceneObject.objectReferenceValue = pgo;
            }
            else
            {
                parentSceneObject.objectReferenceValue = null;
            }

            EditorGUILayout.PropertyField(clusterType, gc_ClusterType);
            MB3_MeshBakerGrouper.ClusterType gg = (MB3_MeshBakerGrouper.ClusterType)clusterType.enumValueIndex;
            if ((gg == MB3_MeshBakerGrouper.ClusterType.none && !(tbg.grouper is MB3_MeshBakerGrouperNone)) ||
                (gg == MB3_MeshBakerGrouper.ClusterType.grid && !(tbg.grouper is MB3_MeshBakerGrouperGrid)) ||
                (gg == MB3_MeshBakerGrouper.ClusterType.pie && !(tbg.grouper is MB3_MeshBakerGrouperPie)) ||
                (gg == MB3_MeshBakerGrouper.ClusterType.agglomerative && !(tbg.grouper is MB3_MeshBakerGrouperCluster))
                )
            {
                tbg.CreateGrouper(gg, tbg.data);
                tbg.clusterType = gg;
            }

            if (clusterType.enumValueIndex == (int)MB3_MeshBakerGrouper.ClusterType.grid)
            {
                EditorGUILayout.PropertyField(gridOrigin, gc_GridOrigin);
                EditorGUILayout.PropertyField(cellSize, gc_CellSize);
            }
            else if (clusterType.enumValueIndex == (int)MB3_MeshBakerGrouper.ClusterType.pie)
            {
                EditorGUILayout.PropertyField(gridOrigin, gc_GridOrigin);
                EditorGUILayout.PropertyField(numSegments, gc_NumSegements);
                EditorGUILayout.PropertyField(pieAxis, gc_PieAxis);
                EditorGUILayout.PropertyField(pieRingSpacing, gc_PieRingSpacing);
                EditorGUILayout.PropertyField(pieCombineAllInCenterRing, gc_PieCombineAllInCenterRing);
            }
            else if (clusterType.enumValueIndex == (int)MB3_MeshBakerGrouper.ClusterType.agglomerative)
            {
                float dist    = clusterDistance.floatValue;
                float maxDist = 100f;
                float minDist = .000001f;
                MB3_MeshBakerGrouperCluster cl = null;
                if (tbg.grouper is MB3_MeshBakerGrouperCluster)
                {
                    cl      = (MB3_MeshBakerGrouperCluster)tbg.grouper;
                    maxDist = cl._ObjsExtents;
                    minDist = cl._minDistBetweenClusters;
                    if (dist < minDist)
                    {
                        dist = Mathf.Lerp(minDist, maxDist, .11f);
                    }
                }

                dist = EditorGUILayout.Slider(gc_ClusterDistance, dist, minDist, maxDist);
                clusterDistance.floatValue = dist;

                string btnName = "Refresh Clusters";
                if (cl.cluster == null || cl.cluster.clusters == null || cl.cluster.clusters.Length == 0)
                {
                    btnName = "Click To Build Clusters";
                }
                if (GUILayout.Button(btnName))
                {
                    if (tbg.grouper is MB3_MeshBakerGrouperCluster)
                    {
                        MB3_MeshBakerGrouperCluster cg = (MB3_MeshBakerGrouperCluster)tbg.grouper;
                        if (tb != null)
                        {
                            cg.BuildClusters(tb.GetObjectsToCombine(), updateProgressBar);
                            EditorUtility.ClearProgressBar();
                            Repaint();
                        }
                    }
                }
            }

            EditorGUILayout.PropertyField(clusterOnLMIndex, gc_ClusterOnLMIndex);
            EditorGUILayout.PropertyField(clusterByLODLevel, gc_ClusterByLODLevel);
            EditorGUILayout.PropertyField(includeCellsWithOnlyOneRenderer, gc_IncludeCellsWithOnlyOneRenderer);
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Prefab Output Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(prefabOptions_autoGeneratePrefabs, gc_prefabOptions_autoGeneratePrefabs);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(prefabOptions_outputFolder, gc_prefabOptions_outputFolder);
            if (GUILayout.Button("Browse"))
            {
                string path = EditorUtility.OpenFolderPanel("Browse For Output Folder", "", "");
                path = MB_BatchPrefabBakerEditorFunctions.ConvertFullPathToProjectRelativePath(path);
                prefabOptions_outputFolder.stringValue = path;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Mesh Baker Settings", EditorStyles.boldLabel);
            EditorGUILayout.HelpBox("These settings will be shared by all created Mesh Bakers.", MessageType.Info);

            UnityEngine.Object oldObjVal = mbSettingsAsset.objectReferenceValue;
            EditorGUILayout.PropertyField(mbSettingsAsset, gc_Settings);

            bool doingTextureArrays = false;

            if (tb != null && tb.textureBakeResults != null)
            {
                doingTextureArrays = tb.textureBakeResults.resultType == MB2_TextureBakeResults.ResultType.textureArray;
            }
            if (mbSettingsAsset.objectReferenceValue == null)
            {
                meshBakerSettingsMe.DrawGUI(tbg.meshBakerSettings, true, doingTextureArrays);
            }
            else
            {
                if (meshBakerSettingsExternal == null || oldObjVal != mbSettingsAsset.objectReferenceValue)
                {
                    UnityEngine.Object targetObj;
                    string             propertyName;
                    ((MB3_MeshCombinerSettings)mbSettingsAsset.objectReferenceValue).GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj);
                    SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName);
                }

                meshBakerSettingsExternal.DrawGUI(((MB3_MeshCombinerSettings)mbSettingsAsset.objectReferenceValue).data, false, doingTextureArrays);
            }
        }
Exemple #3
0
        public override void OnInspectorGUI()
        {
            prefabBaker.Update();

            EditorGUILayout.HelpBox(
                "This tool speeds up the process of preparing prefabs" +
                " for static and dynamic batching. It creates duplicate prefab assets and meshes" +
                " that share a combined material. Source assets are not touched.\n\n" +
                "1) Create instances of source prefabs to this scene.\n" +
                "2) Add these instances to the TextureBaker on this GameObject and bake the textures used by the prefabs.\n" +
                "2) Using the BatchPrefabBaker component, click 'Populate Prefab Rows From Texture Baker' or manually set up Prefab Rows by dragging to the Prefab Rows list.\n" +
                "4) Choose a folder where the result prefabs will be stored and click 'Create Empty Result Prefabs'\n" +
                "5) click 'Batch Bake Prefabs'\n" +
                "6) Check the console for messages and errors\n" +
                "7) (Optional) If you want to compare the source objects to the result objects use the BatchPrefabBaker '...' menu command 'Create Instances For Prefab Rows'. This will create aligned instances of the prefabs in the scene so that it is easy to see any differences.\n", MessageType.Info);
            EditorGUILayout.PropertyField(logLevel, GUIContentLogLevelContent);

            EditorGUILayout.PropertyField(prefabRows, true);

            EditorGUILayout.LabelField("Output Folder", EditorStyles.boldLabel);
            EditorGUILayout.LabelField(outputFolder.stringValue);

            if (GUILayout.Button("Browse For Output Folder"))
            {
                string path = EditorUtility.OpenFolderPanel("Browse For Output Folder", "", "");
                path = MB_BatchPrefabBakerEditorFunctions.ConvertFullPathToProjectRelativePath(path);
                outputFolder.stringValue = path;
            }

            if (GUILayout.Button("Create Empty Result Prefabs"))
            {
                MB_BatchPrefabBakerEditorFunctions.CreateEmptyOutputPrefabs(outputFolder.stringValue, (MB3_BatchPrefabBaker)target);
            }

            Color oldColor = GUI.backgroundColor;

            GUI.backgroundColor = buttonColor;
            if (GUILayout.Button(GUIContentBatchBakePrefabReplacePrefab))
            {
                MB3_BatchPrefabBaker pb = (MB3_BatchPrefabBaker)target;
                MB_BatchPrefabBakerEditorFunctions.BakePrefabs(pb, true);
            }
            if (GUILayout.Button(GUIContentBatchBakePrefabOnlyMeshesAndMats))
            {
                MB3_BatchPrefabBaker pb = (MB3_BatchPrefabBaker)target;
                MB_BatchPrefabBakerEditorFunctions.BakePrefabs(pb, false);
            }
            GUI.backgroundColor = oldColor;

            if (GUILayout.Button("Poplate Prefab Rows From Texture Baker"))
            {
                PopulatePrefabRowsFromTextureBaker((MB3_BatchPrefabBaker)prefabBaker.targetObject);
            }

            if (GUILayout.Button("Open Replace Prefabs In Scene Window"))
            {
                MB3_BatchPrefabBaker pb = (MB3_BatchPrefabBaker)target;
                MB_ReplacePrefabsInSceneEditorWindow.ShowWindow(pb.prefabRows);
            }


            prefabBaker.ApplyModifiedProperties();
            prefabBaker.SetIsDifferentCacheDirty();
        }