zoukankan      html  css  js  c++  java
  • Unity里获取Material里所有的Texture

    Unity里获取Material里所有的Texture

    背景:通过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);
    	}
     
    }
  • 相关阅读:
    转:.net面试题及答案(一)
    高兴!
    游标中LOCAL的意思
    九度 1333
    在进程槽中为进程分配一个空闲位置并分配一个进程号
    USACO Section 1.2 Milking Cows
    九度 1334
    USACO Section 1.3 Mixing Milk
    USACO Section 1.3 Calf Flac
    USACO Section 1.3 Prime Cryptarithm
  • 原文地址:https://www.cnblogs.com/muyouking/p/6531829.html
Copyright © 2011-2022 走看看