UnityEditor——利用Prefab的Refrences引用来查找预制体的组件

前言:

项目进行到后期,老板觉得之前的美术效果不好,让美术出一个新的进度条美术效果图,将之前全部面板的滑块全替换掉。想了半天也没有什么合适的方法,因为每个面板的需求和样式不同,每个滑块的预制体设置肯定是不一样的,如果全部一键替换的话可能会出现更大的问题。手动替换的话这么多预制体都不知道到底有哪些有滑块哪些没有用到滑块,决定于是写一个工具遍历UIPrefab,先将使用滑块的预制体路径输出出来,然后手动替换滑块。

知识概要:

  1. 首先,预制可以直接使用二进制编辑器查看里面内容,里面有组成这个预制体全部的相关信息,如下图所示。
  2. 通过Prefab-> Byte [] - > string可以得到这个Prefab的字符串,只需要知道该字符串中是否包含UnityEngine.UI.Slider即可。

UnityEditor——利用Prefab的Refrences引用来查找预制体的组件_第1张图片

 

源码奉上:

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

namespace Editor
{
	public class CheckRefrencesSlider : EditorWindow
	{

		[SerializeField] private string _strUiPerfabPath;
		
		private Vector2 _scrollPos;

		private List _prefabList;

		private List _resPrefabs;

		private string _currentPerfabPath;

		private string _sliderType;

		[MenuItem("Tools/Ui/Slider引用分析",false,3)]
		public static void CheckSlider()
		{
			Open();
		}

		public static void Open()
		{
			var rect = new Rect(0, 0, 200, 200);
			GetWindowWithRect(typeof(CheckRefrencesSlider),rect,true);
		}

		private void OnGUI()
		{
			GUILayout.Space(10);
			GUI.backgroundColor = Color.grey;
			if (GUILayout.Button("获取sliderPath",GUILayout.Height(50)))
			{
				Init();
				GetAllPrefabs(_strUiPerfabPath);
				CheckPrefab();
				
				for (int i = 0; i < _resPrefabs.Count; i++)
				{
					Debug.Log("预制路径为:"+_resPrefabs[i]);
				}
			}
			GUILayout.Space(10);
		}

		private void Init()
		{
			_strUiPerfabPath = "Assets/Prefab/Ui/";
			_sliderType = "UnityEngine.UI.Slider";

			if (_prefabList == null)
			{
				_prefabList = new List();
			}
			_prefabList.Clear();

			if (_resPrefabs == null)
			{
				_resPrefabs = new List();
			}
			_resPrefabs.Clear();
		}

		/// 
		/// 检测prefab
		/// 
		private void CheckPrefab()
		{
			if (_prefabList == null || _prefabList.Count == 0)	return;
			
			_resPrefabs.Clear();
			for (int i = 0; i < _prefabList.Count; i++)
			{
				EditorUtility.DisplayProgressBar("搜索预制体", "搜索中" + _prefabList[i], i / _prefabList.Count);
				FileStream fs = new FileStream(_prefabList[i],FileMode.Open,FileAccess.Read);
				byte[] buff = new byte[fs.Length];
				fs.Read(buff, 0, (int) fs.Length);
				string strText = Encoding.Default.GetString(buff);

				if (strText.Contains(_sliderType))
				{
					_resPrefabs.Add(_prefabList[i]);
				}
			}
			
			EditorUtility.ClearProgressBar();
			
		}

		
		/// 
		/// 获取路径下全部的prefab
		/// 
		/// 
		private void GetAllPrefabs(string strPrefabsPath)
		{
			//获取路径目录
			var dirArr = Directory.GetDirectories(strPrefabsPath);
			for (int i = 0; i < dirArr.Length; i++)
			{
				var pathArr = GetFiles(dirArr[i]);
				for (int j = 0; j < pathArr.Length; j++)
				{
					var filePath = pathArr[j];
					_prefabList.Add(filePath);
				}
			}

			var paths = GetFiles(strPrefabsPath);
			for (int i = 0; i < paths.Length; i++)
			{
				var filePath = paths[i];
				_prefabList.Add(filePath);
			}
			
			Debug.Log("AllPrefabCount.."+_prefabList.Count);

		}

		/// 
		///  获取目录下的所有对象路径,except mate
		/// 
		/// 路径
		/// 是否递归获取
		/// 
		private string[] GetFiles(string path, bool recursive = true)
		{
			var resultList = new List();

			var dirArr = Directory.GetFiles(path, "*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
			for (int i = 0; i < dirArr.Length; i++)
			{
				if (Path.GetExtension(dirArr[i]) != ".meta")
				{
					resultList.Add(dirArr[i].Replace('\\','/'));
				}
			}

			return resultList.ToArray();
		}
	}
}

输出结果:

UnityEditor——利用Prefab的Refrences引用来查找预制体的组件_第2张图片

可以看到,一共有70多个预制需要替换滑块,蛤?!70多个,Emmm,又是一个不眠之夜!

你可能感兴趣的:(UnityEditor——利用Prefab的Refrences引用来查找预制体的组件)