Unity批量替换资源

Unity 批量替换资源

使用炒鸡方便 可以指定文件夹 进行替换

上代码。。有不足或Bug 欢迎提出

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

public class ReplaceAssets : EditorWindow
{

    private static Object targetOld,targetNew;
    private static ReplaceAssets replaceAssets;
    static string oldGuid, newGuid, limitedPath, limitedPath_show;
    [MenuItem("Assets/ReplaceAssets", false, 12)]
    private static void Open()
    {
        oldGuid = string.Empty;
        newGuid = string.Empty;
        limitedPath_show = "Assets/";
        limitedPath = Application.dataPath;
        targetOld = null;
        targetNew = null;
        replaceAssets = null;
        replaceAssets = GetWindow<ReplaceAssets>();
        replaceAssets.Show();
        if (Selection.activeObject) targetOld = Selection.activeObject;
    }
    private void OnGUI()
    {
        GUILayout.Label("旧资源");
        GUILayout.BeginHorizontal("Box");
        targetOld = EditorGUILayout.ObjectField("OldValue:", targetOld, typeof(Object), false) as Object;
        if (targetOld)
        {
            oldGuid = targetOld.GetType() == typeof(UnityEngine.Texture2D) || targetOld.GetType() == typeof(UnityEngine.Sprite)
            ? GetTexture2DAndSprideStr(targetOld)
            : AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetOld));
        }
        GUILayout.EndHorizontal();
        GUILayout.Label("新资源");
        GUILayout.BeginHorizontal("Box");
        targetNew = EditorGUILayout.ObjectField("NewValue:", targetNew, typeof(Object), false) as Object;
        if (targetNew)
        {
            newGuid = targetNew.GetType() == typeof(UnityEngine.Texture2D) || targetNew.GetType() == typeof(UnityEngine.Sprite)
            ? GetTexture2DAndSprideStr(targetNew)
            : AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetNew));
        }
        GUILayout.EndHorizontal();
        GUILayout.Label("限定修改目录");
        GUILayout.BeginHorizontal("Box");
        limitedPath_show = EditorGUILayout.TextField("替换范围为", limitedPath_show);
        if (GUILayout.Button("选择路径",GUILayout.Width(120)))
        {
            string selectResult = EditorUtility.OpenFolderPanel(title, Application.dataPath, "Assets");
            if (!string.IsNullOrEmpty(selectResult))
            {
                limitedPath = selectResult;
                limitedPath_show = limitedPath.Replace(Application.dataPath, "Assets");
            }
        }
        GUILayout.EndHorizontal();
        if (GUILayout.Button("替换资源"))
        {
            if (!string.IsNullOrEmpty(oldGuid) && !string.IsNullOrEmpty(newGuid)) FindAssets();
            else
            {
                UnityEngine.Debug.Log("oldGuid--->" + oldGuid);
                UnityEngine.Debug.Log("newGuid--->" + newGuid);
            }
        }
    }


    private static void FindAssets()
    {
        UnityEngine.Debug.LogWarning("oldGuid--->" + oldGuid);
        UnityEngine.Debug.LogWarning("newGuid--->" + newGuid);
        replaceAssets.Close();
        List<string> withoutExtensions = new List<string>() { ".prefab", ".unity", ".mat", ".asset" };
        string[] files = System.IO.Directory.GetFiles(limitedPath, "*.*", System.IO.SearchOption.AllDirectories)
        .Where(s => withoutExtensions.Contains(System.IO.Path.GetExtension(s).ToLower())).ToArray();
        int startIndex = 0;
        EditorApplication.update = delegate ()
        {
            bool isCancel = EditorUtility.DisplayCancelableProgressBar("匹配资源中", files[startIndex], (float)startIndex / (float)files.Length);
            string objTxt = File.ReadAllText(files[startIndex]);
            if (Regex.IsMatch(objTxt, oldGuid))
            {
                objTxt = objTxt.Replace(oldGuid, newGuid);
                File.WriteAllText(files[startIndex], objTxt);
                Debug.Log(files[startIndex], AssetDatabase.LoadAssetAtPath<Object>(files[startIndex].Replace(Application.dataPath, "Assets")));
            }
            startIndex++;
            if (isCancel || startIndex >= files.Length)
            {
                EditorUtility.ClearProgressBar();
                EditorApplication.update = null;
                startIndex = 0;
                Selection.activeObject = null;
                AssetDatabase.Refresh();
                EditorUtility.DisplayDialog("资源替换", "替换完成", "OK");
            }
        };
    }

    private static string GetTexture2DAndSprideStr(Object obj)
    {
        string path = AssetDatabase.GetAssetPath(obj);
        string guid = AssetDatabase.AssetPathToGUID(path);
        string fileID = string.Empty;
        if (obj.GetType() == typeof(UnityEngine.Texture2D)) fileID = "21300000";
        else if (obj.GetType() == typeof(UnityEngine.Sprite))
        {
            if (AssetDatabase.LoadAllAssetsAtPath(path).Length <= 2) fileID = "21300000";
            else
            {
                string fileName = obj.name;
                string matchName = fileName;
                bool isHaveChinese = false;
                for (int i = 0; i < fileName.Length; i++)
                {
                    if ((int)fileName[i] > 127)
                    {
                        if (!isHaveChinese) isHaveChinese = true;
                        matchName = matchName.Replace(fileName[i].ToString(), String2Unicode(fileName[i].ToString()));
                    }
                }
                string metaPath = path + ".meta";
                string[] metaTxt = File.ReadAllLines(metaPath);
                if (isHaveChinese) matchName = "\"" + matchName + "\"";
                string matchContent = string.Format(": {0}", matchName);
                for (int i = 0; i < metaTxt.Length; i++)
                {
                    if (metaTxt[i].Contains(matchContent))
                    {
                    if (metaTxt[i].Contains(matchContent))
                    {
#if UNITY_2019
                        fileID = metaTxt[i-1].Split(':')[1].Trim();
#else
                        fileID = metaTxt[i].Split(':')[0].Trim();
#endif
                        break;
                    }
                }
            }
        }
        else return null;
        return string.IsNullOrEmpty(fileID) ? string.Empty : string.Format("fileID: {0}, guid: {1}", fileID, guid);
    }
    /// <summary>
    /// <summary>
    /// 字符串转Unicode
    /// </summary>
    /// <param name="source">源字符串</param>
    /// <returns>Unicode编码后的字符串</returns>
    public static string String2Unicode(string source)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(source);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < bytes.Length; i += 2)
        {
            stringBuilder.AppendFormat("\\u{0}{1}", bytes[i + 1].ToString("x").PadLeft(2, '0').ToUpper(), bytes[i].ToString("x").PadLeft(2, '0').ToUpper());
        }
        return stringBuilder.ToString();
    }

    /// <summary>
    /// Unicode转字符串
    /// </summary>
    /// <param name="source">经过Unicode编码的字符串</param>
    /// <returns>正常字符串</returns>
    public static string Unicode2String(string source)
    {
        return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(
                     source, x => string.Empty + System.Convert.ToChar(System.Convert.ToUInt16(x.Result("$1"), 16)));
    }

}


版权声明:本文为ClumsySmurf原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。