public SerializedProperty GetIterator();
返回SerializedProperty类
objectReferenceValue 参数:Object索引的相关obj
///
/// 检查项目中Missing的Component
/// 如果Component的某些引用丢失,打印报错信息,打印丢失引用GameObject的路径
///
public class ReferenceCheck {
[MenuItem("Tool/CheckLoseReferenceObj")]
static void CheckLoseRefObj()
{
GameObject[] Gos = GetSceneObjects();
foreach (GameObject item in Gos)
{
List components = new List();
item.GetComponents(components);
foreach (var component in components)
{
if (!component)
{
Debug.LogError("Missing Component:" + FullPath(item));
continue;
}
SerializedObject so = new SerializedObject(component);
var iter = so.GetIterator();
while (iter.NextVisible(true))
{
if(iter.propertyType == SerializedPropertyType.ObjectReference)
{
//引用对象是null并且引用ID不是0 说明丢失了引用
if (iter.objectReferenceValue == null && iter.objectReferenceInstanceIDValue != 0)
{
Debug.LogError("Component miss property:" + FullPath(item));
}
}
}
}
}
}
private static GameObject[] GetSceneObjects()
{
return Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[];//遍历整个场景
}
private static string FullPath(GameObject go)
{
if (go.transform.parent != null)
{
return FullPath(go.transform.parent.gameObject) + "/" + go.name;
}
else
{
return go.name;
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class RefTool : EditorWindow
{
[MenuItem("Tools/检查/检查MissingReference资源")]
public static void FindMissing()
{
Find();
foreach (var item in refPaths)
{
Debug.Log(item);
}
}
private static Dictionary> prefabs = new Dictionary>();
private static Dictionary refPaths = new Dictionary();
private static void Find()
{
prefabs.Clear();
string[] allassetpaths = AssetDatabase.GetAllAssetPaths();
//获取所有资源路径
var gos = allassetpaths
.Where(a => a.EndsWith("prefab"))//筛选 是以prefab为后缀的 预设体资源
.Select(a => AssetDatabase.LoadAssetAtPath(a));//加载这个预设体
//gos拿到的是所有加载好的预设体
foreach (var item in gos) {
GameObject go = item as GameObject;
if (go) {
Component[] cps = go.GetComponentsInChildren(true);//获取这个物体身上所有的组件
foreach (var cp in cps)//遍历每一个组件
{
if (!cp)
{
if (!prefabs.ContainsKey(go))
{ prefabs.Add(go, new List() { cp });
} else
{ prefabs[go].Add(cp);
} continue;
}
SerializedObject so = new SerializedObject(cp);//生成一个组件对应的S俄日阿里则对Object对象 用于遍历这个组件的所有属性
var iter = so.GetIterator();//拿到迭代器
while (iter.NextVisible(true))//如果有下一个属性
{ //如果这个属性类型是引用类型的
if (iter.propertyType == SerializedPropertyType.ObjectReference)
{ //引用对象是null 并且 引用ID不是0 说明丢失了引用
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() { cp });
}
}
}
}
}
}
}
EditorUtility.DisplayDialog("", "就绪", "OK");
}
}
filter中可以包括名称、标签或者类型(类名称)
Name:
名称通过空格隔开当成一个独立的名字来搜索。比如"Texture Player",隔开的字段可以用来筛选,Texture和Player都可以进行查找
Labels:Assets可以通过labels附加来进行查找,Assets可以通过关键字'l:'加一个label来进行查找。
Types:在资源类型前加关键字't:',来过滤字符串中包含多个类型。
Types(包括以下):
Prefab
Object
Shader
Material
Texture
Font
Flare
Cubemap
public static string[] FindAssets(string filter);
public static string[] FindAssets(string filter, string[] searchInFolders);
当使用带路径的重载的时候,路径是一个字符串数组,并且这个路径是"Assets"这样的相对路径,此方法会遍历路径下全部文件包括,目标文件下的全部子文件。
SerializedObject
and SerializedProperty are classes for editing properties on objects in a completely generic way that automatically handles undo and styling UI for prefabs.
SerializedObject is used in conjunction with SerializedProperty and Editor classes.
这个版本将原本的函数进一步抽象,将简单的方法暴露,方便编程人员的使用
提高资源检查的和复用性,在Match方法中,如果是场景,通过EditorSceneManager.OpenScene打开场景,通过此方法的返回值scene,调用方法GetRootGameObjects,拿到场景中的根GameObjects,在遍历Root下面的全部GameObjects
如果不是Scene文件,是其他类型的资产,直接使用AssetDatabase.LoadAllAssetsAtPath方法,拿到全部资产,将全部资产遍历,使用序列化的方式遍历每个资产。
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.IO;
using System.Linq;
using System.Collections;
namespace SPGF.Tools
{
public static class FindMissingReferences
{
[MenuItem("Tools/Find Missing References (UI)", false, 200)]
static private void RunUI()
{
var artsPath = Path.Combine(Utils.GetArtsPath(), "Canvases");
Run("t:Prefab", new string[] { artsPath });
}
[MenuItem("Tools/Find Missing References (Efxs)", false, 201)]
static private void RunEfxs()
{
var artsPath = Path.Combine(Utils.GetArtsPath(), "Effects");
Run("t:Prefab", new string[] { artsPath });
}
[MenuItem("Tools/Find Missing References (Scene)", false, 202)]
static private void RunScenes()
{
var artsPath = Path.Combine(Utils.GetArtsPath(), "Scenes");
Run("t:Scene", new string[] { artsPath });
}
static void Run(string pattern, string[] paths)
{
var iterator = Match(pattern, paths).GetEnumerator();
EditorApplication.update = delegate ()
{
if (!iterator.MoveNext())
{
EditorUtility.ClearProgressBar();
EditorApplication.update = null;
}
};
}
private static IEnumerable Match(string pattern, string[] paths)
{
var files = AssetDatabase.FindAssets(pattern, paths)
.Select(item => AssetDatabase.GUIDToAssetPath(item))
.ToArray();
for (var i = 0; i < files.Length; i++)
{
var file = files[i];
var ctx = AssetDatabase.LoadAssetAtPath