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

}

时间: 2024-10-09 03:09:24

Unity里获取Material里所有的Texture的相关文章

获取WebView里的网页文本内容

获取WebView里的网页文本内容,能够採用例如以下方法: public class ComJSInterface { public void loadHtmlContent(String content) { Log.d("comJs", "html:" + content); } } mWebView.addJavascriptInterface(new ComJSInterface(), "comjs"); mWebView.loadUrl

[WPF] 动画Completed事件里获取执行该动画的UI对象

原文:[WPF] 动画Completed事件里获取执行该动画的UI对象 昨天群里有位童鞋提出如何在动画完成事件Completed里获取到执行该动画的UI对象. WPF里动画的Completed的本身并不会返回执行动画的UI对象,但我们可以利用附加属性Storyboard.TargetProperty来达到我们想要的效果. 步骤: 1 在执行动画前,先附加属性记录对象 DoubleAnimation ani = new DoubleAnimation(); ani.From = start; an

图片内容保存到数据库,并从数据库里获取图片

保存image到database public bool SaveImage(string filePath) { bool isSuccess = false; string FilePath = filePath; string filename = FilePath.Substring(FilePath.LastIndexOf("\\") + 1); //得到上传文件的文名 string filetext = string.Empty; FileStream fs = new F

不可变字典 赋值 求字典里有多少对 获取字典里所有value值 获取所有考值

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { /*字典:NSDictionary 存储数据用的   和数组的区别:字典使用键值方式.无序的 2 相当于我们使用字典通过目录来查找具体字的解释 3 用key-value的形式数据,value作用用来存储数据,key用来检索数据 4 cocoa中的字典:可变/不可变 注意: 1.key通常是字符串对象,可以是

(转)从海康7816的ps流里获取数据h264数据

海康7816使用ps流来封装h.264数据,这里使用的解码器无法识别ps流,因此需要将h264数据从ps流里提取出来 对于ps流的规定可以参考13818-1文档 这里从7816里获取到一些数据取样 00 00 01 BA 44 73 26 B8 34 01 00 00 03 FE FF FF 00 00 00 0100 00 01 BC00 5A E0 FF 00 24 40 0E 48 4B 00 01 0D AF C5 D3 E0 07 FF FF FF FF 41 12 48 4B 00

获取作用域里的值的4种方法

获取作用域里的值的4种方法: 1.java代码: <%request.getAttribute()%> 2.${requestScope/username} 3.<s:property value="#session.username"> 4.不知道作用域时候: <s:property value="#attr.username"/>

easyui-在iframe里获取现阶段选中的tab的标题

在iframe里获取当前选中的tab的标题(easyui) var currTab =$$('#tabs').tabs('getSelected'); console.info(currTab.panel('options').title);

android 获取手机里面的WIFI密码

获取手机里面的WIFI密码??刚看到的时候我也没明白这个有什么用,自己的手机不会不知道wifi密码吧,所以到现在我也没用到个这个功能 ,在这里权当记录一下,以备以后再找. 话说怎么获取WIFI密码还得从小米手机说起,记得小米推出了个Wifi密码共享的功能:比如在一个咖啡厅,只要一个人向服务员获取了密码,然后他打开wifi密码共享,那么其他人就可以直接连上wifi,而不需要再向服务员询问密码.但是后来安全什么的东西,最后这项功能好像也就无疾而终了.. 不过我们还是可以看一下小米是怎么实现的: 1.

Javascript 获取地址栏里(URL)传递的参数

有时我们需要在js文件中用URL传来的参数,但是Javascript是客户端执行的脚本语言,而Session是服务器端的对象,我们不能直接取得Session中的值.那么,我们该如何在JS文件中获取URL中的参数呢? 下面介绍两种方式,一种是字符串拆分法,另一种是正则匹配法. 第一种:字符串拆分法 这种方式是通过location.search方法取得URL中的参数部分,然后再进一步处理得到的.具体代码如下: [javascript] //获取地址栏里(URL)传递的参数 function GetR