欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UnityEditor——扫描配置文件中配置的资源路径是否正确

程序员文章站 2022-03-21 23:48:49
...

在开发过程中,对于游戏中使用的美术资源,很多时候都是配置在配置文件中的,但是随着不断地开发,配置文件和美术资源可能都经历了多次更新,很有可能深藏在配置文件中的资源路径是不对的,可以通过扫描配置文件,将所有的路径记录下来,然后在检查是否通过路径可以加载到对应资源的方式来检测。

在这里提供一下大体思路和代码,具体项目需要具体分析。

该脚本用于将配置文件中的路径存起来。

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

// ReSharper disable once CheckNamespace
namespace Game.model
{
    public abstract class GenConfigArtRefsBase
    {
        public abstract void GetRefs(List<string> allList);

        public static void Gen(HashSet<string> hashSet){
            List<string> toWrite = new List<string>();
            List<GenConfigArtRefsBase> ret = new List<GenConfigArtRefsBase>();
            ret.Add(new GenConfActivityLordTaskEvent());
            ret.Add(new GenConfAllianceBuildingPage());
            ret.Add(new GenConfAllianceGift());
            ret.Add(new GenConfAllianceIcon());

            foreach (var genConfigArtRefsBase in ret)
            {
                toWrite.Add("-------------------------------------------------------------------------------------------------------------------------------------------------------- " + genConfigArtRefsBase.GetType());
                var resList = new List<string>();
                genConfigArtRefsBase.GetRefs(resList);
                resList.Sort();
                toWrite.AddRange(resList);
            }
            
            StringBuilder sb = new StringBuilder();
            foreach (var s in toWrite)
            {
                var process = s.Trim().Trim('/','\\');
                if (string.IsNullOrEmpty(process)) continue;
                hashSet.Add(process.ToLower());
            }
            foreach (var s in hashSet)
            {
                sb.AppendLine(s);
            }
            
            File.WriteAllText(Path.Combine(Application.dataPath, "../配置文件引用的资源白名单.txt"), sb.ToString());
        }
    }

    public class GenConfActivityLordTaskEvent:GenConfigArtRefsBase
    {
        public override void GetRefs(List<string> allList){
            foreach (var cfg in ConfActivityLordTaskEvent.Datas)
            {
                allList.Add(cfg.Value.EventImage);

            }
        }
    }
    public class GenConfAllianceBuildingPage:GenConfigArtRefsBase
    {
        public override void GetRefs(List<string> allList){
            foreach (var cfg in ConfAllianceBuildingPage.Datas)
            {
                allList.Add(cfg.Value.Icon);

            }
        }
    }
    public class GenConfAllianceGift:GenConfigArtRefsBase
    {
        public override void GetRefs(List<string> allList){
            foreach (var cfg in ConfAllianceGift.Datas)
            {
                allList.Add(cfg.Value.Icon);

            }
        }
    }
    public class GenConfAllianceIcon:GenConfigArtRefsBase
    {
        public override void GetRefs(List<string> allList){
            foreach (var cfg in ConfAllianceIcon.Datas)
            {
                allList.Add(cfg.Value.Image);

            }
        }
    }
    

}

Editor方法,在运行时使用,这个方法除了扫描配置文件,还扫描了UI预制及代码中引用的资源,具体情况具体分析。

[MenuItem("Tools/输出配置文件引用资源列表")]
        public static void GenCodeRefs()
        {
            if (!Application.isPlaying)
            {
                EditorUtility.DisplayDialog("", "请在运行模式下操作", "OK");
                return;
            }
            HashSet<string> toWrite = new HashSet<string>();
            FieldInfo[] props = typeof(UiType).GetFields(BindingFlags.NonPublic | BindingFlags.Public |
                                                         BindingFlags.DeclaredOnly | BindingFlags.Static);
            foreach (var prop in props)
            {
                var attrs = prop.GetCustomAttributes(typeof(UiTypeInfoAttribute), false) as UiTypeInfoAttribute[];
                if (attrs != null && attrs.Length > 0)
                {
                    UiTypeInfoAttribute info = attrs[0];
                    var s = string.Format("{0}/{1}", string.Format(ResManager.UiFormat, info.Prefab), info.Prefab);
                    toWrite.Add(s.ToLower());
                }
            }

            props = typeof(ArtResReferences).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic);
            foreach (var prop in props)
            {
                if (prop.FieldType == typeof(string))
                {
                    var data = prop.GetValue(null) as string;
                    if (string.IsNullOrEmpty(data)) continue;
                    toWrite.Add(data.ToLower());
                }else if (prop.FieldType == typeof(string[]))
                {
                    var data = prop.GetValue(null) as string[];
                    if (data == null) continue;
                    foreach (var s in data)
                    {
                        if (string.IsNullOrEmpty(s)) continue;
                        toWrite.Add(s.ToLower());
                    }
                }
            }
            
            GenConfigArtRefsBase.Gen(toWrite);
        }
    }

执行过后会在工程根目录下生成文件:配置文件引用的资源白名单

这个方法是根据生成的资源名单,逐条分析查找是否能根据资源路径找到资源。

[MenuItem("Tools/检查配置文件的路径是否正确")]
    public static void CheckConfig()
    {
        HashSet<string> toWrite = new HashSet<string>();
        var w1 = Path.Combine(Application.dataPath, "Plugins/Editor/ResUtil/配置文件引用的资源白名单.txt");
        string config = "";
        if (File.Exists(w1))
        {
            using (var f = File.OpenText(w1))
            {
                while (!f.EndOfStream)
                {
                    var line = f.ReadLine();
                    if (string.IsNullOrEmpty(line)) continue;
                    if (line.Contains("---"))
                    {
                        config = line.Replace("--------------------------------------------------------------------------------------------------------------------------------------------------------","");
                    }
                    string abPath = string.Empty;
                    string abName = string.Empty;
                    ValidatePath(line.ToLower(), ref abPath, ref abName);
                    string[] path = new string[0];;
                    var ab = string.Format("{0}{1}", abPath, ".assetbundle").ToLower();
                    path = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(ab, abName.ToLower());
                    if (path.Length>0)
                    {
                        var obj = AssetDatabase.LoadAssetAtPath(path[0], typeof(object));
                        if (obj == null)
                        {
                            toWrite.Add("配置文件:[" + config + "]=====" + "配置文件路径错误: [" + line.ToLower() +
                                        "]======================");
                        }
                    }
                    else
                    {
                        if (!line.Contains("-----"))
                        {
                            toWrite.Add("配置文件:[" + config + "]=====" + "配置文件路径错误: [" + line.ToLower() +
                                        "]======================");
                        }
                    }
                }
            }
        }
        
        StringBuilder sb = new StringBuilder();
        foreach (var s in toWrite)
        {
            sb.AppendLine(s);
        }
            
        File.WriteAllText(Path.Combine(Application.dataPath, "../配置文件引用的资源错误名单.txt"), sb.ToString());
    }

扫描结果如图所示

UnityEditor——扫描配置文件中配置的资源路径是否正确

相关标签: Unity