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); } } }
/// <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); } } }
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); } }
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 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); }