背景:通过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);
}
}
原文地址:http://www.tuicool.com/articles/bqyi22Y