UnityEditor——查找一个美术资源在项目中全部预制的引用并输出预制路径(多线程法)

本文介绍如何在UnityEditor中通过多线程查找特定美术资源在项目所有预制体中的引用,并输出预制体的完整路径。当资源不再使用时,此方法可以帮助清理无用的资源。

在项目后期,美术面板换了几波后变得十分庞大,有大量旧的美术资源可能已经被弃用了,需要删掉,可以通过这个方式查找某个资源在全部预制中的引用并输出路径,如果没有引用了可以删掉,代码如下

 

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

namespace Editor
{
	public static class FindReferences
	{
		private static EditorApplication.CallbackFunction _updateDelegate;

		public delegate List<string> ThreadRun(ThreadPars par);
		
		private const int ThreadCount = 4;
		
		public class ThreadPars
		{
			public List<string> CheckList = new List<string>();
			public string AimGuid;
		}

		private static List<string> ThreadFind(ThreadPars par)
		{
			List<string> ret = new List<string>();
			if (par != null)
			{
				foreach (var file in par.CheckList)
				{
					if (Regex.IsMatch(File.ReadAllText(file),par.AimGuid))
					{
						ret.Add(file);
					}
				}
			}

			return ret;
		}

		[MenuItem("Assets/Find References Thread",false,10)]
		private static void FindThread()
		{
			EditorSettings.serializationMode = SerializationMode.ForceText;
			EditorHelper.OpenConsole();
			EditorHelper.ClearConsole();
			AssetDatabase.Refresh();
			string path = AssetDatabase.GetAssetPath(Selection.activeObject);
			if (!string.IsNullOrEmpty(path))
			{
				string guid = AssetDatabase.AssetPathToGUID(path);
				List<string> withoutExtensions = new List<string>() {".prefab", ".unity", ".mat", ".asset"};
				string[] files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
					.Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();

				ThreadPars[] threadParses = new ThreadPars[ThreadCount];
				for (int i = 0; i < ThreadCount; i++)
				{
					threadParses[i] = new ThreadPars();
					threadParses[i].AimGuid = guid;
				}

				for (int i = 0; i < files.Length; i++)
				{
					int index = i % ThreadCount;
					threadParses[index].CheckList.Add(files[i]);
				}

				ThreadRun[] tRun = new ThreadRun[ThreadCount];
				int finishedState = ThreadCount;
				
				IAsyncResult[] results = new IAsyncResult[ThreadCount];
				
				_updateDelegate = delegate
				{
					var finishedCount = 0;
					for (int i = 0; i < ThreadCount; i++)
					{
						if (results[i].IsCompleted) ++finishedCount;
					}
					
					EditorUtility.DisplayProgressBar("匹配资源中",string.Format("进度:{0}",finishedCount),finishedCount *1f/ThreadCount);

					if (finishedCount >= finishedState)
					{
						List<string> re = new List<string>();
						for (int i = 0; i < ThreadCount; i++)
						{
							re.AddRange(tRun[i].EndInvoke(results[i]));
						}

						foreach (var s in re)
						{
							Debug.Log(s, AssetDatabase.LoadAssetAtPath<Object>(GetRelativeAssetsPath(s)));
						}
						EditorUtility.ClearProgressBar();
						EditorApplication.update -= _updateDelegate;
					}
				};

				for (int i = 0; i < ThreadCount; i++)
				{
					tRun[i] = ThreadFind;
					results[i] = tRun[i].BeginInvoke(threadParses[i], null, null);
				}

				EditorApplication.update += _updateDelegate;
			}

		}

		private static string GetRelativeAssetsPath(string path)
		{
			return "Assets" + Path.GetFullPath(path).Replace(Path.GetFullPath(Application.dataPath), "").Replace('\\','/');
		}	
	}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值