Unity里获取Material里所有的Texture

来源:互联网 发布:excel两列数据找相同 编辑:程序博客网 时间:2024/05/29 10:13
背景:通过Material获取Texture的接口有:Material.mainTexture, Material.GetTexture(string propertyName); 但没有一个接口可以直接获取Material的所有textures.

解决方法一:
利用资源依赖,EditorUtility. CollectDependencies()。
static string [] GetMaterialTexturePaths( Material _mat )    {        List<string > results = new List <string>();        Object[] roots = new Object[] { _mat };        Object[] dependObjs = EditorUtility. CollectDependencies(roots );        foreach (Object dependObj in dependObjs )        {            if (dependObj .GetType() == typeof(Texture2D ))            {                string texpath = AssetDatabase.GetAssetPath (dependObj. GetInstanceID());                results.Add (texpath);            }        }        return results .ToArray();    }


解决方法二:
利用序列化,得到Shader的Property,从而得到Shader里Texture相关的PropertyName。 Unity4.1版本以上,ShaderUtil已经提供相应接口。
static string[] GetCertainMaterialTexturePaths(Material _mat)    {        List<string > results = new List<string >();        Shader shader = _mat.shader;        for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i)        {            if (ShaderUtil .GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType .TexEnv)            {                string propertyName = ShaderUtil .GetPropertyName(shader, i);                Texture tex = _mat.GetTexture(propertyName);                string texPath = AssetDatabase .GetAssetPath(tex.GetInstanceID());                results.Add(texPath);            }        }        return results.ToArray();    }

对于ShaderUtil不提供对外接口的低版本,还有方法,参考http://answers.unity3d.com/questions/179255/a-way-to-iterateenumerate-shader-properties.html
using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using UnityEditor;using UnityEngine;using System.IO;using System.Collections; public static class ShaderUtilInterface{    public static Dictionary<string, MethodInfo> methods = new Dictionary<string, MethodInfo>();     static ShaderUtilInterface()    {        var asm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a=>a.GetTypes().Any(t=>t.Name == "ShaderUtil"));        if(asm != null)        {            var tp = asm.GetTypes().FirstOrDefault(t=>t.Name == "ShaderUtil");            foreach(var method in tp.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))            {                methods[method.Name] = method;            }        }    }     public static List<Texture> GetTextures(this Material shader)    {        var list = new List<Texture>();        var count = shader.GetPropertyCount();        for(var i = 0; i < count; i++)        {            if(shader.GetPropertyType(i)==4)            {                list.Add((Texture)shader.GetProperty(i));            }        }        return list;    }     public static int GetPropertyCount(this Material shader)    {        return Call<int>("GetPropertyCount", shader.shader);    }     public static int GetPropertyType(this Material shader, int index)    {        return Call<int>("GetPropertyType", shader.shader, index);    }     public static string GetPropertyName(this Material shader, int index)    {        return Call<string>("GetPropertyName", shader.shader, index);    }     public static void SetProperty(this Material material, int index, object value)    {        var name = material.GetPropertyName(index);        var type = material.GetPropertyType(index);        switch(type)        {        case 0:            material.SetColor(name, (Color)value);            break;        case 1:            material.SetVector(name, (Vector4) value);            break;        case 2:            material.SetFloat(name, (float)value);            break;        case 3:            material.SetFloat(name, (float)value);            break;        case 4:            material.SetTexture(name, (Texture) value);            break;        }    }       public static object GetProperty(this Material material, int index)    {        var name = material.GetPropertyName(index);        var type = material.GetPropertyType(index);        switch(type)        {        case 0:            return material.GetColor(name);         case 1:            return material.GetVector(name);          case 2:        case 3:            return material.GetFloat(name);         case 4:            return material.GetTexture(name);         }    return null;    }     public static T Call<T>(string name, params object[] parameters)    {        return (T)methods[name].Invoke(null, parameters);    } }






0 0