IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity 材质无用的引用清理 -> 正文阅读

[游戏开发]Unity 材质无用的引用清理

整理资源的时候 发现材质属性面板上只有四张贴图 但是材质球确有五张贴图的依赖 想着写个工具处理下 没想到网上一搜已经有小哥写好了工具 直接拿来用了

原文链接

代码上做了简洁

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System;
using UnityEngine;
using UnityEditor;

/// <summary>
/// 如果材质使用了带有两张贴图的Shader 并且对贴图赋了值 
/// 再切换到带有一张贴图的Shader 此时就会有一张冗余贴图在材质中
/// 浪费内存 浪费加载带宽
/// </summary>
static class MaterialCleanerTools
{
    [UnityEditor.MenuItem("Assets/Tools/清理材质无用贴图")]
    public static void ClearMaterial()
    {
        UnityEngine.Object[] objects = Selection.GetFiltered(typeof(object), SelectionMode.Assets);
        if (objects.Length == 0)
        {
            Debug.LogWarning("请选择资源目录后再进行操作");
            return;
        }

        foreach (var obj in objects)
        {
            float index = 0;
            string assetPath = AssetDatabase.GetAssetPath(obj);
            string projectPath = Application.dataPath.Replace("Assets", "");
            string fullPath = EditorPathUtils.ToUnixPath(projectPath + assetPath);
            List<string> filePaths = EditorUtils.CollectFilesByEnd(fullPath, ".mat");
            foreach (string filePath in filePaths)
            {
                string fileAssetPath = filePath.Replace(Application.dataPath, "Assets");
                ClearMaterialAsset(fileAssetPath);
                index++;
                EditorUtility.DisplayProgressBar("清理材质无用的缓存属性", fileAssetPath, index / (float)filePaths.Count);
            }
        }

        EditorUtility.ClearProgressBar();
    }
    public static void ClearMaterialAsset(string path)
    {
        if (String.IsNullOrEmpty(path))
        {
            return;
        }

        Material m = AssetDatabase.LoadAssetAtPath<Material>(path);
        if (m == null)
            return;

        var deps = AssetDatabase.GetDependencies(new String[] { path });
        var deps_textures = deps.Where(s => IsTextureAsset(s)).ToList();
        var used_textures = new HashSet<String>();
        var shader = m.shader;
        var newMat = new Material(shader);
        var c = ShaderUtil.GetPropertyCount(shader);

        for (int i = 0; i < c; ++i)
        {
            var type = ShaderUtil.GetPropertyType(shader, i);
            var name = ShaderUtil.GetPropertyName(shader, i);
            var value = m.GetProperty(i);
            switch (type)
            {
                case ShaderUtil.ShaderPropertyType.Color:
                    {
                        newMat.SetColor(name, m.GetColor(name));
                    }
                    break;
                case ShaderUtil.ShaderPropertyType.Float:
                    {
                        newMat.SetFloat(name, m.GetFloat(name));
                    }
                    break;
                case ShaderUtil.ShaderPropertyType.Range:
                    {
                        newMat.SetFloat(name, (float)value);
                    }
                    break;
                case ShaderUtil.ShaderPropertyType.TexEnv:
                    {
                        newMat.SetTexture(name, (Texture)value);
                        newMat.SetTextureOffset(name, m.GetTextureOffset(name));
                        newMat.SetTextureScale(name, m.GetTextureScale(name));
                        var tpath = AssetDatabase.GetAssetPath((Texture)value);
                        if (!String.IsNullOrEmpty(tpath))
                        {
                            used_textures.Add(tpath);
                        }
                    }
                    break;
                case ShaderUtil.ShaderPropertyType.Vector:
                    {
                        newMat.SetVector(name, (Vector4)value);
                    }
                    break;
            }
        }
        bool rebuild = false;
        if (used_textures.Count != deps_textures.Count)
        {
            for (int i = 0; i < deps_textures.Count; ++i)
            {
                var _fn = deps_textures[i];
                if (!used_textures.Contains(_fn))
                {
                    rebuild = true;
                    UnityEngine.Debug.LogWarning(String.Format("unused texture: {0}", _fn));
                }
            }
        }
        if (!rebuild)
        {
            if (newMat != null)
            {
                UnityEngine.Object.DestroyImmediate(newMat);
            }
            return;
        }

        string basePath = Path.GetFullPath(path + "/../").Replace(Path.GetFullPath(Application.dataPath), "Assets");
        string fn = Path.GetFileNameWithoutExtension(path);
        string ext = Path.GetExtension(path);

        //SplitFullFilename(path, out fn, out ext, out basePath);
        var tempAssetPath = String.Format("{0}{1}_temp.{2}", basePath, fn, ext);
        var _test = AssetDatabase.LoadAllAssetsAtPath(tempAssetPath);

        if (_test != null)
        {
            AssetDatabase.DeleteAsset(tempAssetPath);
        }

        // create a new material to replace it latter
        AssetDatabase.CreateAsset(newMat, tempAssetPath);
        Resources.UnloadAsset(newMat);

        var tempAssetDataPath = String.Format("{0}{1}_datatemp.bytes", basePath, fn, ext);
        if (File.Exists(tempAssetPath))
        {
            // rename it to .bytes
            File.Copy(tempAssetPath, tempAssetDataPath, true);
            // delete temp material
            AssetDatabase.DeleteAsset(tempAssetPath);
            if (File.Exists(tempAssetDataPath))
            {
                // delete original material
                File.Delete(path);
                // replace original material with .bytes file
                File.Copy(tempAssetDataPath, path, true);
                // remove bytes file
                File.Delete(tempAssetDataPath);
                AssetDatabase.Refresh();
            }
        }
        
        return;
    }

    static object GetProperty(this Material material, int index)
    {
        var name = ShaderUtil.GetPropertyName(material.shader, index);
        var type = ShaderUtil.GetPropertyType(material.shader, index);
        switch (type)
        {
            case ShaderUtil.ShaderPropertyType.Color:
                return material.GetColor(name);
            case ShaderUtil.ShaderPropertyType.Vector:
                return material.GetVector(name);
            case ShaderUtil.ShaderPropertyType.Range:
            case ShaderUtil.ShaderPropertyType.Float:
                return material.GetFloat(name);
            case ShaderUtil.ShaderPropertyType.TexEnv:
                return material.GetTexture(name);
        }
        return null;
    }

    static bool IsTextureAsset(String assetPath)
    {
        var ext = Path.GetExtension(assetPath).ToLower();
        return ext == ".png" ||
            ext == ".tga" ||
            ext == ".jpg" ||
            ext == ".bmp" ||
            ext == ".psd" ||
            ext == ".dds" ||
            ext == ".exr";
    }
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:58:02  更:2022-02-28 15:58:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:49:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码