132 lines
5.2 KiB
C#
132 lines
5.2 KiB
C#
|
//Ҫ<>̳<EFBFBD>EditorWindow<6F><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>Լ<EFBFBD><D4BC>Ŀ<EFBFBD><C4BF><EFBFBD>
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using UnityEditor;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
public class FindMissingWindow : EditorWindow
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
[MenuItem("<22><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>/<2F><>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>/<2F><><EFBFBD>鶪ʧ<E9B6AA><CAA7><EFBFBD>õ<EFBFBD>Animator<6F><72>Դ")]
|
|||
|
public static void FindMissing()
|
|||
|
{
|
|||
|
GetWindow<FindMissingWindow>().titleContent = new GUIContent("<22><><EFBFBD><EFBFBD>Missing<6E><67>Դ");
|
|||
|
GetWindow<FindMissingWindow>().Show();
|
|||
|
Find();
|
|||
|
}
|
|||
|
private static Dictionary<UnityEngine.Object, List<UnityEngine.Object>> prefabs = new Dictionary<UnityEngine.Object, List<UnityEngine.Object>>();
|
|||
|
private static Dictionary<UnityEngine.Object, string> refPaths = new Dictionary<UnityEngine.Object, string>();
|
|||
|
private static void Find()
|
|||
|
{
|
|||
|
prefabs.Clear();
|
|||
|
string[] allassetpaths = AssetDatabase.GetAllAssetPaths();//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ·<D4B4><C2B7>
|
|||
|
var gos = allassetpaths
|
|||
|
.Where(a => a.EndsWith("prefab"))//ɸѡ <20><><EFBFBD><EFBFBD>prefabΪ<62><CEAA><EFBFBD><D7BA> Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
|
|||
|
.Select(a => AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(a));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>
|
|||
|
//gos<6F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC>غõ<D8BA>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>
|
|||
|
foreach (var item in gos)
|
|||
|
{
|
|||
|
GameObject go = item as GameObject;
|
|||
|
if (go)
|
|||
|
{
|
|||
|
Component[] cps = go.GetComponentsInChildren<Component>(true);//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
foreach (var cp in cps)//<2F><><EFBFBD><EFBFBD>ÿһ<C3BF><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
if (!cp)
|
|||
|
{
|
|||
|
if (!prefabs.ContainsKey(go))
|
|||
|
{
|
|||
|
prefabs.Add(go, new List<UnityEngine.Object>() { cp });
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
prefabs[go].Add(cp);
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
SerializedObject so = new SerializedObject(cp);//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>S<EFBFBD><53><EFBFBD>հ<EFBFBD><D5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Object<63><74><EFBFBD><EFBFBD> <20><><EFBFBD>ڱ<EFBFBD><DAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
var iter = so.GetIterator();//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
while (iter.NextVisible(true))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>
|
|||
|
if (iter.propertyType == SerializedPropertyType.ObjectReference)
|
|||
|
{
|
|||
|
//<2F><><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD>null <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ID<49><44><EFBFBD><EFBFBD>0 ˵<><CBB5><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (iter.objectReferenceValue == null && iter.objectReferenceInstanceIDValue != 0)
|
|||
|
{
|
|||
|
if (!refPaths.ContainsKey(cp)) refPaths.Add(cp, iter.propertyPath);
|
|||
|
else refPaths[cp] += " | " + iter.propertyPath;
|
|||
|
if (prefabs.ContainsKey(go))
|
|||
|
{
|
|||
|
if (!prefabs[go].Contains(cp)) prefabs[go].Add(cp);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
prefabs.Add(go, new List<UnityEngine.Object>() { cp });
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
EditorUtility.DisplayDialog("", "<22><><EFBFBD><EFBFBD>", "OK");
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD>ֻ<EFBFBD>ǽ<EFBFBD><C7BD><EFBFBD><EFBFBD>ҽ<EFBFBD><D2BD><EFBFBD><EFBFBD><EFBFBD>ʾ
|
|||
|
private Vector3 scroll = Vector3.zero;
|
|||
|
private void OnGUI()
|
|||
|
{
|
|||
|
scroll = EditorGUILayout.BeginScrollView(scroll);
|
|||
|
EditorGUILayout.BeginVertical();
|
|||
|
if (GUILayout.Button("<22>Ƴ<EFBFBD><C6B3><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD>õ<EFBFBD>Animator<6F><72><EFBFBD><EFBFBD>")) RemoveAnimatorWithMissReference();
|
|||
|
foreach (var item in prefabs)
|
|||
|
{
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
EditorGUILayout.ObjectField(item.Key, typeof(GameObject), true, GUILayout.Width(200));
|
|||
|
EditorGUILayout.BeginVertical();
|
|||
|
foreach (var cp in item.Value)
|
|||
|
{
|
|||
|
if (cp)
|
|||
|
{
|
|||
|
EditorGUILayout.BeginHorizontal();
|
|||
|
EditorGUILayout.ObjectField(cp, cp.GetType(), true, GUILayout.Width(200));
|
|||
|
if (refPaths.ContainsKey(cp))
|
|||
|
{
|
|||
|
GUILayout.Label(refPaths[cp]);
|
|||
|
}
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
}
|
|||
|
}
|
|||
|
EditorGUILayout.EndVertical();
|
|||
|
EditorGUILayout.EndHorizontal();
|
|||
|
}
|
|||
|
EditorGUILayout.EndVertical();
|
|||
|
EditorGUILayout.EndScrollView();
|
|||
|
}
|
|||
|
|
|||
|
private void RemoveAnimatorWithMissReference()
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
foreach (var cps in prefabs.Values)
|
|||
|
{
|
|||
|
foreach (var item in cps)
|
|||
|
{
|
|||
|
Animator a = item as Animator;
|
|||
|
if (a)
|
|||
|
{
|
|||
|
count++;
|
|||
|
EditorUtility.SetDirty(a.gameObject);
|
|||
|
DestroyImmediate(a, true);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (count > 0)
|
|||
|
{
|
|||
|
EditorUtility.DisplayDialog("", "һ<><D2BB><EFBFBD>Ƴ<EFBFBD>" + count + "<22><>Animator<6F><72><EFBFBD><EFBFBD>", "OK");
|
|||
|
AssetDatabase.SaveAssets();
|
|||
|
AssetDatabase.Refresh();
|
|||
|
Find();
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|