Skip to content

Instantly share code, notes, and snippets.

@yangruihan
Created July 25, 2018 03:24
Show Gist options
  • Select an option

  • Save yangruihan/bd229b02320aa096910234824c449904 to your computer and use it in GitHub Desktop.

Select an option

Save yangruihan/bd229b02320aa096910234824c449904 to your computer and use it in GitHub Desktop.
Unity 根据脚本名,查找引用该脚本的Prefab
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEditor;
using Object = UnityEngine.Object;
public class UIScriptRefChecker : EditorWindow
{
public const string PREFAB_SUFFIX = "*.prefab";
[MenuItem("Tools/【工具】脚本引用扫描")]
public static void ReplaceButtonResource()
{
var window = GetWindow<UIScriptRefChecker>();
window.minSize = new Vector2(410, 750);
window.Show();
}
public class Data
{
public GameObject rootObj;
public GameObject childObj;
}
private string _typeName;
private List<Data> _objs = new List<Data>();
private Object _folder;
private Vector2 _scrollViewPos;
private int _currentProgress = 0;
private int _totalCount = 0;
public void OnGUI()
{
GUILayout.BeginHorizontal();
GUILayout.Label("脚本名(包含命名空间)");
_typeName = EditorGUILayout.TextField(_typeName);
GUILayout.EndHorizontal();
GUILayout.Space(20);
GUILayout.BeginHorizontal();
_folder = EditorGUILayout.ObjectField("源目录", _folder, typeof(Object));
GUILayout.EndHorizontal();
GUILayout.Space(20);
if (_objs != null && _objs.Count > 0)
{
GUILayout.Label("Result: ");
_scrollViewPos = EditorGUILayout.BeginScrollView(_scrollViewPos, GUILayout.Width(400), GUILayout.Height(600));
for (int i = 0; i < _objs.Count; i++)
{
var data = _objs[i];
GUILayout.BeginHorizontal();
if (GUILayout.Button(data.rootObj.name))
{
PingObj(data.rootObj);
}
if (GUILayout.Button(data.childObj.name))
{
PingObj(data.childObj);
}
GUILayout.EndHorizontal();
}
EditorGUILayout.EndScrollView();
}
GUILayout.FlexibleSpace();
if (GUILayout.Button("开始扫描"))
{
if (!string.IsNullOrEmpty(_typeName))
{
StartScan();
}
}
}
private void StartScan()
{
Type type = GetType(_typeName.Trim());
if (type == null)
{
EditorUtility.DisplayDialog("错误", "脚本类型错误,请检查命名空间及脚本名称", "确定");
}
string path = Application.dataPath;
if (_folder != null)
{
path += AssetDatabase.GetAssetPath(_folder).Replace("Assets", "");
}
if (string.IsNullOrEmpty(path))
{
EditorUtility.DisplayDialog("错误", "请检查扫描路径", "确定");
return;
}
var prefabs = new List<GameObject>();
prefabs.AddRange(LoadDiectoryPrefab(path));
_objs.Clear();
_currentProgress = 0;
_totalCount = prefabs.Count;
EditorUtility.DisplayProgressBar("扫描中...", "开始扫描", 0f);
for (int i = 0; i < _totalCount; i++)
{
var prefab = prefabs[i];
if (prefab == null)
continue;
EditorUtility.DisplayProgressBar("扫描中...", string.Format("{0} ({1}/{2})", prefab.name, _currentProgress, _totalCount), _currentProgress++ * 1f / _totalCount);
var comps = prefab.transform.root.GetComponentsInChildren(type, true);
if (comps != null)
{
foreach (var comp in comps)
{
Data data = new Data();
data.rootObj = comp.transform.root.gameObject;
data.childObj = comp.gameObject;
_objs.Add(data);
}
}
}
EditorUtility.ClearProgressBar();
EditorUtility.DisplayDialog("扫描完成", string.Format("共找到{0}个包含该脚本的prefab", _objs.Count), "确定");
}
private Type GetType(string typeName)
{
typeName = typeName.Trim();
Assembly assembly = Assembly.GetExecutingAssembly();
Type ret = Type.GetType(typeName);
if (ret == null)
{
if (typeName.StartsWith("UnityEngine"))
{
assembly = Assembly.Load("UnityEngine");
}
else if (typeName.StartsWith("UnityEditor"))
{
assembly = Assembly.Load("UnityEditor");
}
else
{
assembly = Assembly.LoadFile(Path.Combine(Path.GetDirectoryName(assembly.Location), "Assembly-CSharp.dll"));
}
return assembly == null ? null : assembly.GetType(typeName);
}
return ret;
}
private List<GameObject> LoadDiectoryPrefab(string rootPath)
{
FileInfo[] fileInfos = GetDirectoryFileInfos(rootPath, PREFAB_SUFFIX);
if (fileInfos != null)
{
var ret = new List<GameObject>();
EditorUtility.DisplayProgressBar("加载Prefab中...", "开始加载", 0f);
int i = 0;
foreach (FileInfo files in fileInfos)
{
string path = files.FullName;
string assetPath = GetAssetsUnityRelativePath(path);
EditorUtility.DisplayProgressBar("加载Prefab中...", assetPath, ++i * 1.0f / fileInfos.Length);
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
ret.Add(prefab);
}
EditorUtility.ClearProgressBar();
return ret;
}
return null;
}
private void PingObj(GameObject obj)
{
EditorGUIUtility.PingObject(obj);
Selection.activeGameObject = obj;
}
private FileInfo[] GetDirectoryFileInfos(string rootPath, string suffix)
{
var dictoryInfo = new DirectoryInfo(rootPath);
if (!dictoryInfo.Exists) return null;
FileInfo[] fileInfos = dictoryInfo.GetFiles(suffix, SearchOption.AllDirectories);
return fileInfos;
}
private string GetAssetsUnityRelativePath(string absolutePath)
{
#if UNITY_STANDALONE_WIN
return absolutePath.Substring(absolutePath.IndexOf("Assets\\")).Replace("\\", "/");
#else
return absolutePath.Substring(absolutePath.IndexOf("Assets/"));
#endif
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment