效果:
先在菜单栏里面找到Tools/CheckPrefab打开窗口
代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
public class CheckPrefabLayers : EditorWindow
{
private Vector2 scrollViewPosition;
[MenuItem("Tools/Check Prefab")]
static void Init()
{
// 创建窗口实例并显示
CheckPrefabLayers window = (CheckPrefabLayers)EditorWindow.GetWindow(typeof(CheckPrefabLayers));
window.Show();
}
void OnGUI()
{
scrollViewPosition = EditorGUILayout.BeginScrollView(scrollViewPosition); // 开始滚动视图
//检查用了指定层级的预制体
CheckReferLayers();
GUILayout.Space(10);
//检查用了指定脚本的预制体
CheckReferScripts();
EditorGUILayout.EndScrollView();
}
#region ---------------------------------检测所有用指定层级的物体----------------------------------
private int selectedLayerIndex = 0;
private List<GameObject> referLayerPrefabs = new List<GameObject>();
private void CheckReferLayers()
{
GUILayout.Label("查找指定层级", EditorStyles.boldLabel);
string[] layerNames = UnityEditorInternal.InternalEditorUtility.layers;
selectedLayerIndex = EditorGUILayout.Popup("检查层级:", selectedLayerIndex, layerNames);
if (GUILayout.Button("查找层级引用"))
{
CheckLayers();
}
ShowPrefabs(referLayerPrefabs);
}
private void CheckLayers()
{
referLayerPrefabs.Clear();
//获取所有物体的GUID
string[] allPrefabGUID = AssetDatabase.FindAssets("t:Prefab");
foreach (string prefabPath in allPrefabGUID)
{
string prefabFullPath = AssetDatabase.GUIDToAssetPath(prefabPath);
// 加载预制体
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabFullPath);
// 检查预制体的 Layer 层级
if (prefab != null && prefab.layer ==selectedLayerIndex)
{
//检测子物体
Transform[] childObjs = prefab.GetComponentsInChildren<Transform>(true);
for (int i = 0; i < childObjs.Length; i++)
{
if (childObjs[i].gameObject.layer == selectedLayerIndex)
{
referLayerPrefabs.Add(prefab);
break;
}
}
}
}
Repaint();
Debug.LogWarning("检测完毕");
}
#endregion
#region ------------------------------检测所有引用此脚本的预制体------------------------------------
private MonoScript targetScript;
private List<GameObject> referScriptPrefabs = new List<GameObject>();
private void CheckReferScripts()
{
GUILayout.Label("查找指定脚本", EditorStyles.boldLabel);
targetScript = (MonoScript)EditorGUILayout.ObjectField("指定脚本", targetScript, typeof(MonoScript), false);
if (GUILayout.Button("查找脚本引用"))
{
FindReferences();
}
ShowPrefabs(referScriptPrefabs);
}
void FindReferences()
{
referScriptPrefabs.Clear();
if (targetScript == null)
{
Debug.LogError("请选择一个脚本");
return;
}
string[] allPrefabGUID = AssetDatabase.FindAssets("t:Prefab");
foreach (var prefabPath in allPrefabGUID)
{
string prefabFullPath = AssetDatabase.GUIDToAssetPath(prefabPath);
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabFullPath);
if (PrefabHasScript(prefab))
{
referScriptPrefabs.Add(prefab);
}
}
Repaint();
Debug.LogWarning("检测完毕");
}
//检测预制体是否有指定脚本
bool PrefabHasScript(GameObject prefab)
{
Type targetType = targetScript.GetClass();
MonoBehaviour[] behaviours = prefab.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour behaviour in behaviours)
{
MonoScript monoScript = MonoScript.FromMonoBehaviour(behaviour);
if (monoScript != null && monoScript.GetClass() == targetType)
{
return true;
}
}
return false;
}
#endregion
#region ------------------------------------将预制体列表显示出来-------------------------------
private void ShowPrefabs(List<GameObject> list)
{
GUILayout.Label("预制体列表展示:", EditorStyles.boldLabel);
foreach (var prefab in list)
{
EditorGUILayout.ObjectField(prefab, typeof(GameObject), false);
}
}
#endregion
}