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版权协议,转载请附上原文出处链接和本声明。