共享一下,有时间会加注释的
起因是这样的,有大概100多个预设,我买的一个场景模型包
但是我不喜欢它的贴图,就自己做了另一套
如果是挨个换材质的话,我肯定会疯掉的啊
就琢磨还是写个编辑器算了
其实,编辑器也没有省时间,一个多小时,边写边测试
其实有这个事件,早就全替换完了
但结果虽然一样,但过程里面有收获啊~~
期间遇到的问题:
1.assetsdata的loadasset方法很操蛋,路径名称不能是全路径,需要相对路径,用doc的话来说就是project路径下的文件位置
这个折磨了我好久,google一下才明白的
2.还是loadallassetsatpath,这个方法的作用和名字严重不一致,一点都不信达雅,并不是读取路径下的所有资源,而是读取一个资源的所有相关资源(fbx模型的话,就是材质,贴图,动画一起读)
3.在editor脚本里面,不要直接访问material,而是sharedMaterial,因为是非运行状态,没有办法缓存新的材质instance
4.如果想要将场景中的预设,通过代码apply的话,就执行这个....这个方法词不达意啊,居然是替换掉....orz
PrefabUtility.ReplacePrefab( go, PrefabUtility.GetPrefabParent( go ), ReplacePrefabOptions.ConnectToPrefab );
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEditor; using System.IO; public class ExchangeMaterial : EditorWindow { // Use this for initialization [MenuItem("Damage/OpenMaterialChange")] static void Init () { EditorWindow.GetWindow<ExchangeMaterial>(true,"ExchangeMaterial"); } [SerializeField] private List<Material> oldMaterials = new List<Material>(); [SerializeField] private List<Material> newMaterials = new List<Material>(); void OnGUI() { if(GUILayout.Button("Add Material") && (oldMaterials.Count == 0)) { string[] paths = Directory.GetFiles(Application.dataPath + "/_Metal/Materials"); int i = Application.dataPath.Length; Debug.Log(paths.Length); foreach(string obj in paths) { if(!obj.Contains("meta")) { string path = obj.Substring(i-6); //path = path.Substring(0,path.Length -4); Debug.Log(path); Material mat = AssetDatabase.LoadAssetAtPath(path,typeof(Material)) as Material; Debug.Log(mat); oldMaterials.Add(mat); newMaterials.Add(null); } } } if(GUILayout.Button(" RemoveMaterial")) { oldMaterials.Clear(); newMaterials.Clear(); } if(GUILayout.Button(" DoneIT")) { ChangeMaterial(); } for(int i = 0 ; i < oldMaterials.Count; i++) { EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); oldMaterials[i] = EditorGUILayout.ObjectField(oldMaterials[i],typeof(Material)) as Material; newMaterials[i] = EditorGUILayout.ObjectField(newMaterials[i],typeof(Material)) as Material; EditorGUILayout.EndHorizontal(); } } void ChangeMaterial() { Renderer[] renderers = GameObject.FindObjectsOfType<Renderer>(); Debug.Log(renderers.Length); foreach(Renderer obj in renderers) { for (int i = 0 ; i < oldMaterials.Count; i++) { if(obj.sharedMaterial == oldMaterials[i]) { Debug.Log("Get it :" + oldMaterials[i].name); if(newMaterials[i] != null) { obj.sharedMaterial = newMaterials[i] ; Debug.Log("Succeed Replace"); } continue; } } } } [MenuItem("Damage/ApplyChange &p")] static void ApplyPrefab() { GameObject[] renderers = GameObject.FindObjectsOfType<GameObject>(); foreach(GameObject go in renderers) { PrefabUtility.ReplacePrefab( go, PrefabUtility.GetPrefabParent( go ), ReplacePrefabOptions.ConnectToPrefab ); } } }