Example #1
0
        /// <summary>
        /// Sorts the Material Remaps by names.
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        public static void SortRemaps(this SyncPrefabScriptedImporter syncPrefabImporter)
        {
            var so = new SerializedObject(syncPrefabImporter);

            var sourceRemaps = so.FindProperty("m_MaterialRemaps");
            var unsortedList = new List <string>();

            for (int i = 0; i < sourceRemaps.arraySize; i++)
            {
                SerializedProperty item = sourceRemaps.GetArrayElementAtIndex(i);
                unsortedList.Add(item.FindPropertyRelative("syncMaterialName").stringValue);
            }

            var sortedList = new List <string>(unsortedList);

            sortedList.Sort();

            for (int destinationIndex = 0; destinationIndex < sortedList.Count; destinationIndex++)
            {
                var sourceIndex = unsortedList.FindIndex(x => x == sortedList[destinationIndex]);
                sourceRemaps.MoveArrayElement(sourceIndex, destinationIndex);

                var item = unsortedList[sourceIndex];
                unsortedList.RemoveAt(sourceIndex);
                if (destinationIndex > sourceIndex)
                {
                    destinationIndex--;
                }
                unsortedList.Insert(destinationIndex, item);
            }

            so.ApplyModifiedProperties();
            syncPrefabImporter.SaveAndReimport();
        }
        internal static void ResetRemaps(SyncPrefabScriptedImporter importer)
        {
            // disabling auto extract for next import
            var auto = ReflectEditorPreferences.autoExtractMaterialsOnImport;

            ReflectEditorPreferences.autoExtractMaterialsOnImport = false;
            importer.ResetRemaps();
            ReflectEditorPreferences.autoExtractMaterialsOnImport = auto;
        }
Example #3
0
        public static void ExtractMaterial(this SyncPrefabScriptedImporter syncPrefabImporter, string materialName, string targetPath, bool bypassRemappedMaterials = true, bool assignRemaps = false, Action <Material> postExtractAction = null)
        {
            // TODO : implement single material extraction
            if (targetPath.Length != 0)
            {
                // getting existing remaps
                var existingRemaps = new Dictionary <string, Material>();
                syncPrefabImporter.GetRemaps(out existingRemaps);

                // initializing new remaps
                var extractedRemaps = new Dictionary <string, Material>();

                // getting all materials from imported objects
                var materials = new List <Material>();
                syncPrefabImporter.GetImportedMaterials(out materials);

                // find material index // TODO : sorting materials by remaps order ?
                var index = materials.FindIndex(m => m.name == materialName);

                if (bypassRemappedMaterials && existingRemaps.ContainsValue(materials[index]))
                {
                    return;
                }

                // duplicating material to destination
                var      sourceName = materials[index].name;
                Material mCopy      = new Material(materials[index]);
                postExtractAction?.Invoke(mCopy);
                AssetDatabase.CreateAsset(mCopy, targetPath);
                extractedRemaps.Add(sourceName, mCopy);

                // saving new materials
                AssetDatabase.SaveAssets();

                if (assignRemaps)
                {
                    var newRemaps = new Dictionary <string, Material>();

                    // mixing existing and extracted remaps
                    foreach (KeyValuePair <string, Material> kvp in existingRemaps)
                    {
                        if (kvp.Value == null && extractedRemaps.ContainsKey(kvp.Key))
                        {
                            newRemaps[kvp.Key] = extractedRemaps[kvp.Key];
                        }
                        else
                        {
                            newRemaps[kvp.Key] = existingRemaps[kvp.Key];
                        }
                    }

                    syncPrefabImporter.SetRemaps(newRemaps);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Extracts Imported Materials and assigns Remaps.
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        /// <param name="targetPath">Assets relative path to save new materials to.</param>
        /// <param name="bypassRemappedMaterials">Bypass already remapped materials.</param>
        /// <param name="assignRemaps">Automatically assign remaps after extraction.</param>
        /// <param name="postExtractAction">Action to call on extracted material.</param>
        public static void ExtractMaterials(this SyncPrefabScriptedImporter syncPrefabImporter, string targetPath, bool bypassRemappedMaterials = true, bool assignRemaps = false, Action <Material> postExtractAction = null)
        {
            if (targetPath.Length != 0)
            {
                // getting existing remaps
                var existingRemaps = new Dictionary <string, Material>();
                syncPrefabImporter.GetRemaps(out existingRemaps);

                // initializing new remaps
                var extractedRemaps = new Dictionary <string, Material>();

                // getting all materials from imported objects
                var materials = new List <Material>();
                syncPrefabImporter.GetImportedMaterials(out materials);

                // duplicating materials to destination
                foreach (Material m in materials)
                {
                    if (bypassRemappedMaterials && existingRemaps.ContainsValue(m))
                    {
                        continue;
                    }
                    Material mCopy = new Material(m);
                    postExtractAction?.Invoke(mCopy);
                    AssetDatabase.CreateAsset(mCopy, Path.Combine(targetPath, m.name + ".mat"));
                    extractedRemaps.Add(mCopy.name, mCopy);
                }

                // saving new materials
                AssetDatabase.SaveAssets();

                if (assignRemaps)
                {
                    var newRemaps = new Dictionary <string, Material>();

                    // mixing existing and extracted remaps
                    foreach (KeyValuePair <string, Material> kvp in existingRemaps)
                    {
                        if (kvp.Value == null && extractedRemaps.ContainsKey(kvp.Key))
                        {
                            newRemaps[kvp.Key] = extractedRemaps[kvp.Key];
                        }
                        else
                        {
                            newRemaps[kvp.Key] = existingRemaps[kvp.Key];
                        }
                    }

                    syncPrefabImporter.SetRemaps(newRemaps);
                }
            }
        }
Example #5
0
        /// <summary>
        /// Returns a List of Material Remapping Names
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        /// <returns>A List of Material Remapping Names</returns>
        public static List <string> GetRemapNames(this SyncPrefabScriptedImporter syncPrefabImporter)
        {
            List <string> names = new List <string>();

            var so = new SerializedObject(syncPrefabImporter);

            var sourceRemaps = so.FindProperty("m_MaterialRemaps");

            for (int i = 0; i < sourceRemaps.arraySize; i++)
            {
                SerializedProperty item = sourceRemaps.GetArrayElementAtIndex(i);
                names.Add(item.FindPropertyRelative("syncMaterialName").stringValue);
            }
            return(names);
        }
Example #6
0
        /// <summary>
        /// Resets the Material Remaps.
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        public static void ResetRemaps(this SyncPrefabScriptedImporter syncPrefabImporter)
        {
            var so = new SerializedObject(syncPrefabImporter);

            var sourceRemaps = so.FindProperty("m_MaterialRemaps");

            for (int i = 0; i < sourceRemaps.arraySize; i++)
            {
                SerializedProperty item = sourceRemaps.GetArrayElementAtIndex(i);
                item.FindPropertyRelative("remappedMaterial").objectReferenceValue = null;
            }

            so.ApplyModifiedProperties();
            syncPrefabImporter.SaveAndReimport();
        }
Example #7
0
        /// <summary>
        /// Provides a Dictionary of Material Remapping Names and Materials
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        /// <param name="remaps"></param>
        public static void GetRemaps(this SyncPrefabScriptedImporter syncPrefabImporter, out Dictionary <string, Material> remaps)
        {
            // using out to force storing result in calling method and prevent multiple calls to this.

            remaps = new Dictionary <string, Material>();

            var so = new SerializedObject(syncPrefabImporter);

            var sourceRemaps = so.FindProperty("m_MaterialRemaps");

            for (int i = 0; i < sourceRemaps.arraySize; i++)
            {
                SerializedProperty item = sourceRemaps.GetArrayElementAtIndex(i);
                remaps.Add(item.FindPropertyRelative("syncMaterialName").stringValue, (Material)item.FindPropertyRelative("remappedMaterial").objectReferenceValue);
            }
        }
Example #8
0
        /// <summary>
        /// Returns a List of Remapping Materials
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        /// <returns>A List of Remapping Materials</returns>
        public static List <Material> GetRemapMaterials(this SyncPrefabScriptedImporter syncPrefabImporter)
        {
            List <Material> materials = new List <Material>();

            var so = new SerializedObject(syncPrefabImporter);

            var sourceRemaps = so.FindProperty("m_MaterialRemaps");

            for (int i = 0; i < sourceRemaps.arraySize; i++)
            {
                SerializedProperty item = sourceRemaps.GetArrayElementAtIndex(i);
                materials.Add((Material)item.FindPropertyRelative("remappedMaterial").objectReferenceValue);
            }

            return(materials);
        }
Example #9
0
        /// <summary>
        /// Collects all materials from Renderers found in the Imported object's hierarchy.
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        /// <param name="materials"></param>
        public static void GetImportedMaterials(this SyncPrefabScriptedImporter syncPrefabImporter, out List <Material> materials)
        {
            // using out to force storing result in calling method and prevent multiple calls to this.

            materials = new List <Material>();
            var root = syncPrefabImporter.GetRoot();

            foreach (Renderer r in root.GetComponentsInChildren <Renderer>())
            {
                foreach (Material m in r.sharedMaterials)
                {
                    if (!materials.Contains(m))
                    {
                        materials.Add(m);
                    }
                }
            }
        }
        static void AssignMaterialRemaps(SyncPrefabScriptedImporter importer)
        {
            if (importer)
            {
                // find all ScriptableObject based remaps
                if (!AssetDatabase.IsValidFolder("Assets/Reflect"))
                {
                    return;
                }

                List <MaterialMappings> remappers = new List <MaterialMappings>();
                foreach (string guid in AssetDatabase.FindAssets("t:MaterialMappings", new string[] { "Assets/Reflect" }))
                {
                    var remapper = AssetDatabase.LoadAssetAtPath <MaterialMappings>(AssetDatabase.GUIDToAssetPath(guid));
                    //if (remapper.enabled)
                    remappers.Add(remapper);
                }

                // sort remaps by priority (to prioritize conflicting remaps)
                //remappers.Sort((a, b) => a.priority.CompareTo(b.priority));

                // for every material names, loop through remaps to find an override
                Dictionary <string, Material> remaps;
                importer.GetRemaps(out remaps);
                var names = importer.GetRemapNames();
                foreach (string name in names)
                {
                    foreach (MaterialMappings remapper in remappers)
                    {
                        var remapperNames = remapper.materialNames;
                        if (remapperNames.Contains(name) && (remaps[name] == null /* || remapper.overwrite*/))
                        {
                            //Debug.Log(string.Format("{0} => {1}", name, remapper.materialRemaps[remapperNames.FindIndex(x => x == name)].remappedMaterial));
                            remaps[name] = remapper[remapperNames.FindIndex(x => x == name)].remappedMaterial;
                            break;
                        }
                    }
                }

                // assign override
                importer.SetRemaps(remaps);
            }
        }
Example #11
0
        /// <summary>
        /// Assign a Dictionary of Material Remapping Names and Materials to Material Remaps
        /// </summary>
        /// <param name="syncPrefabImporter"></param>
        /// <param name="remaps"></param>
        public static void SetRemaps(this SyncPrefabScriptedImporter syncPrefabImporter, Dictionary <string, Material> remaps)
        {
            var so = new SerializedObject(syncPrefabImporter);

            var targetRemaps = so.FindProperty("m_MaterialRemaps");

            targetRemaps.arraySize = remaps.Count;

            var list = remaps.Keys.ToList();

            //list.Sort(); // FIXME : why does this screw up the importer ?

            for (int i = 0; i < list.Count; i++)
            {
                SerializedProperty item = targetRemaps.GetArrayElementAtIndex(i);
                item.FindPropertyRelative("syncMaterialName").stringValue          = list[i];
                item.FindPropertyRelative("remappedMaterial").objectReferenceValue = remaps[list[i]];
            }

            so.ApplyModifiedProperties();
            syncPrefabImporter.SaveAndReimport();
        }
        internal static void ExtractMaterialsFromSyncPrefabImporter(SyncPrefabScriptedImporter importer)
        {
            var targetPath = EditorUtility.SaveFolderPanel(
                "Save Extracted Materials",
                Application.dataPath,
                "");

            if (targetPath == string.Empty)
            {
                return;
            }

            // issue error if path is outside of Project's Assets
            if (!targetPath.StartsWith(Application.dataPath))
            {
                Debug.LogError("Cannot save materials outside of project's assets folder!");
                return;
            }
            targetPath = "Assets" + targetPath.Substring(Application.dataPath.Length);

            System.Action <Material> postAction = ReflectEditorPreferences.convertExtractedMaterials ? materialConversions[(int)ReflectEditorPreferences.extractedMaterialsConverionMethod] : null;
            importer.ExtractMaterials(targetPath, ReflectEditorPreferences.dontExtractRemappedMaterials, ReflectEditorPreferences.autoAssignRemapsOnExtract, postAction);
        }
        internal static void FindMaterialsForSyncPrefabImporter(SyncPrefabScriptedImporter importer)
        {
            var targetPath = EditorUtility.OpenFolderPanel(
                "Pick Materials Location",
                Application.dataPath,
                "");

            if (targetPath == string.Empty)
            {
                return;
            }

            // issue error if path is outside of Project's Assets
            if (!targetPath.StartsWith(Application.dataPath))
            {
                Debug.LogError("Cannot save materials outside of project's assets folder!");
                return;
            }
            targetPath = "Assets" + targetPath.Substring(Application.dataPath.Length);

            var materialsGUIDS = AssetDatabase.FindAssets("t:Material", new string[1] {
                targetPath
            });
            var materials = new Dictionary <string, Material>();

            foreach (string guid in materialsGUIDS)
            {
                var mat = AssetDatabase.LoadAssetAtPath <Material>(AssetDatabase.GUIDToAssetPath(guid));
                if (mat)
                {
                    materials.Add(mat.name, mat);
                }
            }
            var remaps = new Dictionary <string, Material>();

            importer.GetRemaps(out remaps);
            switch (ReflectEditorPreferences.materialSearchMatchType)
            {
            case MaterialMappings.MatchType.A_Equals_B:
                foreach (KeyValuePair <string, Material> kvp in materials)
                {
                    if (remaps.ContainsKey(kvp.Key) && remaps[kvp.Key] == null)     // TODO : add an option to override existing materials ?
                    {
                        remaps[kvp.Key] = kvp.Value;
                    }
                }
                break;

            default:
                var remapsNames = remaps.Keys.ToList();
                foreach (KeyValuePair <string, Material> kvp_m in materials)
                {
                    foreach (string r in remapsNames)
                    {
                        if (MaterialsOverride.Match(kvp_m.Key, r, ReflectEditorPreferences.materialSearchMatchType) && remaps[r] == null)
                        {
                            remaps[r] = kvp_m.Value;
                        }
                    }
                }
                break;
            }
            importer.SetRemaps(remaps);
        }
 internal static void SortRemaps(SyncPrefabScriptedImporter importer)
 {
     importer.SortRemaps();
 }
        internal static void WhiteBoxSyncPrefabImporter(SyncPrefabScriptedImporter importer)
        {
            string path = "Assets/Materials/White Box";

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            Material whiteBoxMaterial;
            var      whiteBoxMaterialPath = Path.Combine(path, "white.mat");

            if (File.Exists(whiteBoxMaterialPath))
            {
                whiteBoxMaterial = AssetDatabase.LoadAssetAtPath <Material>(whiteBoxMaterialPath);
            }
            else
            {
                whiteBoxMaterial = new Material(Shader.Find("Standard"));
                // TODO : set material default values
                whiteBoxMaterial.color = new Color(.9f, .9f, .9f, 1);
                whiteBoxMaterial.SetFloat("_Glossiness", 0.2f);
                AssetDatabase.CreateAsset(whiteBoxMaterial, whiteBoxMaterialPath);
                AssetDatabase.SaveAssets();
            }

            Material glassBoxMaterial;
            var      glassBoxMaterialPath = Path.Combine(path, "glass.mat");

            if (File.Exists(glassBoxMaterialPath))
            {
                glassBoxMaterial = AssetDatabase.LoadAssetAtPath <Material>(glassBoxMaterialPath);
            }
            else
            {
                glassBoxMaterial = new Material(Shader.Find("Standard (Specular setup)"));
                // TODO : set material default values
                glassBoxMaterial.color = new Color(0, 0, 0, 0);
                glassBoxMaterial.SetColor("_SpecColor", new Color(0.32f, 0.4f, 0.4f, 1));
                glassBoxMaterial.SetFloat("_Mode", 3.0f);
                glassBoxMaterial.SetFloat("_Glossiness", 0.9f);
                AssetDatabase.CreateAsset(glassBoxMaterial, glassBoxMaterialPath);
                AssetDatabase.SaveAssets();
            }

            var remaps = new Dictionary <string, Material>();

            importer.GetRemaps(out remaps);

            var remapsNames = remaps.Keys.ToList();

            foreach (string r in remapsNames)
            {
                if (r.ToLower().Contains("glass")) //  TODO : use a more accurate method based on material itself ?
                {
                    remaps[r] = glassBoxMaterial;
                }
                else
                {
                    remaps[r] = whiteBoxMaterial;
                }
            }

            importer.SetRemaps(remaps);
        }
Example #16
0
 /// <summary>
 /// Returns the Imported Object Root Transform.
 /// </summary>
 /// <param name="syncPrefabImporter"></param>
 /// <returns></returns>
 public static Transform GetRoot(this SyncPrefabScriptedImporter syncPrefabImporter)
 {
     return(AssetDatabase.LoadAssetAtPath <Transform>(syncPrefabImporter.assetPath));
 }