美文网首页
Unity-工具-检查未被使用的资源(texture、sprit

Unity-工具-检查未被使用的资源(texture、sprit

作者: 祝你万事顺利 | 来源:发表于2019-07-10 16:52 被阅读0次

美术会有大量的文件资源导入,使用自动化的工具检查资源的使用情况,标记出资源引用为0的资源,用于检查无用的资源。

检查目标文件夹下的资源引用,标记出资源引用数为0的资源。

Directory.GetFiles此方法用来查找文件
采用三个参数的重载Get<wbr>Files(String, String, Search<wbr>Option)
介绍:
Returns the names of files (including their paths) that match the specified search pattern in the specified directory, using a value to determine whether to search subdirectories.
参数:
第二个参数
The search string to match against the names of files in path. This parameter can contain a combination of valid literal path andwildcard (* and ?) characters, but it doesn't support regular expressions.

wildcard :
In software, a wildcard character is a kind of placeholder represented by a single character, such as an asterisk (*), which can be interpreted as a number of literal characters or an empty string. It is often used in file searches so the full name need not be typed


使用IEnumable,代替递归的方法,来进行优化,读取文本将全部能引用的文件中的GUID读取进入一个dictionary,并计数,再对比dictionary和目标文件中的资产guid是否被引用过。时间复杂度降为N+M。


首先将读取全部文本不用后缀的方式,改用AssetDatabase.FindAssets的方式进行文件过滤。
将原本的方法进行进一步的抽象,方便编程人员进行使用方法。
将场景和其他类型文件进行整合,如果是.Unity的场景文件,直接通过GetDependencies方法取得场景全部的引用。
其他文件通过 AssetDatabase.LoadAllAssetsAtPath获取到文件的全部资产,将获得的资产 SerializedObject序列化,再遍历序列化的对象来取得索引对象属性的objectReferenceInstanceIDValue,通过GetAssetPath方法将InstanceID转换为asset路径,再通过AssetDataBase.AssetPathToGUID方法将asset路径转换为GUID存入Dictionary。
最后还是通过对比GUID的方式进行未引用资源的查找。

using UnityEngine;
using UnityEditor;

using System.IO;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace SPGF.Tools
{
    public static class FindUnusedAssets
    {
        [MenuItem("Tools/Find Unused Assets (UI)", false, 100)]
        static private void RunUI()
        {
            var artsPath = Path.Combine(Utils.GetArtsPath(), "Canvases");

            Run(
                "t:Texture t:Animation t:Animator",
                new string[] {
                    artsPath + "/_Animations",
                    artsPath + "/_Textures",
                    artsPath + "/_BackgroundTextures",
                    artsPath + "/_Atlases"
                },
                "t:Scene t:Prefab t:Material t:Animation t:Animator",
                new string[] {
                    artsPath
                }
            );
        }

        [MenuItem("Tools/Find Unused Assets (Efxs)", false, 101)]
        static private void RunEfxs()
        {
            var artsPath = Path.Combine(Utils.GetArtsPath(), "Effects");

            Run(
                //"t:Texture t:Animation t:Animator t:Model",
                "t:Texture t:Animation t:AnimatorController t:Model",
                new string[] {
                    artsPath
                },
                "t:Prefab t:Material t:Animation t:AnimatorController",
                new string[] {
                    artsPath
                }
            );
        }

        private static void Run(string srcPattern, string[] srcPaths, string dstPattern, string[] dstPaths)
        {
            var iterator = Match(srcPattern, srcPaths, dstPattern, dstPaths).GetEnumerator();
            EditorApplication.update = delegate ()
            {
                if (!iterator.MoveNext())
                {
                    EditorUtility.ClearProgressBar();
                    EditorApplication.update = null;
                }
            };
        }

        private static IEnumerable Match(string srcPattern, string[] srcPaths, string dstPattern, string[] dstPaths)
        {
            var files = AssetDatabase.FindAssets(dstPattern, dstPaths)
                .Select(item => AssetDatabase.GUIDToAssetPath(item))
                .ToArray();

            Debug.Log("total files count : " + files.Length);

            var fileGuilds = new Dictionary<string, int>();
            for (var i = 0; i < files.Length; i++)
            {
                var file = files[i];
                if (EditorUtility.DisplayCancelableProgressBar("Searching...", file, (float)i / (float)files.Length))
                    yield break;

                var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(file);
                if (sceneAsset != null)
                {
                    foreach (var assetPath in AssetDatabase.GetDependencies(file, false))
                    {
                        var guid = AssetDatabase.AssetPathToGUID(assetPath);
                        var c = 0;
                        if (!fileGuilds.TryGetValue(guid, out c))
                            fileGuilds.Add(guid, 0);
                        fileGuilds[guid] += 1;
                    }
                }
                else
                {
                    foreach (var obj in AssetDatabase.LoadAllAssetsAtPath(file))
                    {
                        //Change
                        if (obj != null)
                        {
                            SerializedObject so = new SerializedObject(obj);
                            var iter = so.GetIterator();
                            while (iter.Next(true))
                            {
                                if (iter.propertyType == SerializedPropertyType.ObjectReference && iter.objectReferenceInstanceIDValue != 0)
                                {
                                    var assetPath = AssetDatabase.GetAssetPath(iter.objectReferenceInstanceIDValue);
                                    if (!string.IsNullOrEmpty(assetPath))
                                    {
                                        var guid = AssetDatabase.AssetPathToGUID(assetPath);
                                        var c = 0;
                                        if (!fileGuilds.TryGetValue(guid, out c))
                                            fileGuilds.Add(guid, 0);
                                        fileGuilds[guid] += 1;
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Debug.LogError(file);
                        }
                    }
                }

                yield return null;
            }

            var guids = AssetDatabase.FindAssets(srcPattern, srcPaths);
            foreach (var item in guids)
            {
                if (!fileGuilds.ContainsKey(item))
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(item);
                    Debug.LogWarning(string.Format("Found unused asset {0}({1}).", assetPath, item), AssetDatabase.LoadAssetAtPath<Object>(assetPath));
                }
            }
        }
    }
}

相关文章

网友评论

      本文标题:Unity-工具-检查未被使用的资源(texture、sprit

      本文链接:https://www.haomeiwen.com/subject/uzohkctx.html