Unity实现点击Console消息自动选中预制体的方法
·
直接上代码:
官方文档路径:重要的类 - Debug - Unity 手册
参考代码(实际上很简单,但不知为什么网上搜出来的教程要么实现复杂,要么就是答非所问):
Debug.LogWarning($"存在引用----文件 <a href=\"{f}\" line=\"1\">{f}</a>", 这里填入需要定位的GameObject对象);
// 实例参考:
private UnityEngine.Object obj;
Debug.LogWarning($"存在引用----文件 <a href=\"{f}\" line=\"1\">{f}</a>", obj);
// 字符串功能说明: <a href=\"{f}\" line=\"1\">{f}</a>
// 该字符串中的f为需要定位的obj对象的相对路径,例如 “Assets/Res/Prefabs/UI/Test.prefab” ,使用该字符串在点击Console消息后,在Console下方的详细信息中点击资源路径时,可直接打开对应的预制体
最后附带上资源文件引用查询代码参考(注:以下代码需要使用包管理器安装EditorCoroutines 包):
using System.Collections;
using System.IO;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEngine;
/// <summary>
/// 查找资源引用工具
/// </summary>
public class FindAssetReferenceTool
{
private const string FindTip = "未查询到引用该文件的资源";
private const string AssetsPath = "Assets/";
private static bool findResult;
private static Object obj;
private static float currentProcess;
[MenuItem("Assets/查找引用该资源的所有资源")]
private static void FindAssetReference()
{
findResult = true;
obj = Selection.activeObject;
string p = AssetDatabase.GetAssetPath(obj);
string guid = AssetDatabase.AssetPathToGUID(p);
Debug.Log($"当前文件所在路径:{p}");
Debug.Log($"当前文件GUID:{guid}");
EditorCoroutineUtility.StartCoroutineOwnerless(TraverseAllFile(guid, AssetsPath));
}
private static bool CheckReferenceInfo(string guid, string filePath)
{
return File.ReadAllText(filePath).Contains(guid);
}
private static IEnumerator TraverseAllFile(string guid, string path)
{
yield return null;
currentProcess = 0;
while (true)
{
currentProcess++;
string[] files = Directory.GetFiles(path);
string[] directorys = Directory.GetDirectories(path);
bool Cancel = EditorUtility.DisplayCancelableProgressBar($"正常查询对 {obj.name} 资产的所有引用", path, currentProcess / directorys.Length);
foreach (string dir in directorys)
{
yield return TraverseAllFile(guid, dir);
if(Cancel) break;
}
if (Cancel) break;
foreach (string f in files)
{
if (f.EndsWith(".meta")) continue;
if (CheckReferenceInfo(guid, f))
{
Debug.LogWarning($"存在引用----文件 <a href=\"{f}\" line=\"1\">{f}</a>", (obj as GameObject).transform);
findResult = false;
}
if (Cancel) break;
}
break;
}
EditorUtility.ClearProgressBar();
if (findResult && AssetsPath.CompareTo(path) == 0)
Debug.LogWarning(FindTip);
}
}
新补充检索当前场景中引用信息代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Object = UnityEngine.Object;
/// <summary>
/// 查找资源引用工具
/// </summary>
public static class FindAssetReferenceTool
{
private const string FindTip = "未查询到引用该文件的资源";
private const string AssetsPath = "Assets/";
private const string EndsWithStr1 = ".meta";
private static bool findResult;
private static Object obj;
private static float currentProcess;
private static Dictionary<Type, FindAssetsMethodInfo> methods;
private static bool init = false;
private static string fileName;
private static string fileNameExtension;
private static StringBuilder sb;
private static Scene scene;
#region 查询Project中的资源引用
[MenuItem("Assets/查找引用该资源的所有资源")]
private static void FindAssetReference()
{
findResult = true;
obj = Selection.activeObject;
string p = AssetDatabase.GetAssetPath(obj);
string guid = AssetDatabase.AssetPathToGUID(p);
Debug.Log($"当前文件所在路径:{p}", obj);
Debug.Log($"当前文件GUID:{guid}");
fileName = p;
fileNameExtension = p+".meta";
sb = new StringBuilder();
EditorCoroutineUtility.StartCoroutineOwnerless(TraverseAllFile(guid, AssetsPath));
}
private static bool CheckReferenceInfo(string guid, string filePath)
{
return File.ReadAllText(filePath).Contains(guid);
}
private static IEnumerator TraverseAllFile(string guid, string path)
{
yield return null;
currentProcess = 0;
while (true)
{
currentProcess++;
string[] files = Directory.GetFiles(path);
string[] directorys = Directory.GetDirectories(path);
bool Cancel = EditorUtility.DisplayCancelableProgressBar($"正在查询对 {obj.name} 资产的所有引用", path, currentProcess / directorys.Length);
foreach (string dir in directorys)
{
yield return TraverseAllFile(guid, dir);
if(Cancel) break;
}
if (Cancel) break;
foreach (string f in files)
{
sb.Clear();
sb.Append(f);
sb.Replace('\\', '/');
string nf = sb.ToString();
if (nf.ToString().CompareTo(fileName) == 0 || nf.CompareTo(fileNameExtension) == 0) continue;
if (CheckReferenceInfo(guid, f))
{
//Debug.LogWarning($"存在引用----文件:{f}");
if (f.EndsWith(EndsWithStr1))
{
string newP = f.Substring(0, f.LastIndexOf('.'));
Debug.LogWarning($"存在引用----文件 <a href=\"{newP}\" line=\"1\">{newP}</a>", AssetDatabase.LoadAssetAtPath(newP, typeof(Object)));
}
else
Debug.LogWarning($"存在引用----文件 <a href=\"{f}\" line=\"1\">{f}</a>", AssetDatabase.LoadAssetAtPath(f, typeof(Object)));
findResult = false;
}
if (Cancel) break;
}
break;
}
EditorUtility.ClearProgressBar();
bool result = AssetsPath.CompareTo(path) == 0;
if (findResult && result)
Debug.LogWarning(FindTip);
if (result)
sb = null;
System.GC.Collect();
}
#endregion
#region 查询当前场景中的资源引用
private static void Init()
{
if (init) return;
init = true;
methods = new Dictionary<Type, FindAssetsMethodInfo>();
Assembly assembly = typeof(FindAssetReferenceTool).Assembly;
Type[] types = assembly.GetTypes();
Type interfaceType = typeof(ICurrentSceneFindAssetReferenceExpand);
foreach (Type t in types)
{
if (interfaceType != t && interfaceType.IsAssignableFrom(t))
{
MethodInfo[] infos = t.GetMethods();
foreach (MethodInfo info in infos)
{
var a = info.GetCustomAttribute<CurrentSceneFindAssetReferenceExpandAttribute>();
if (a != null)
{
if (methods.ContainsKey(a.type))
{
Debug.LogWarning($"已存在对类型:{a.type} 的查找方法,方法名:{methods[a.type].method.DeclaringType}-{methods[a.type].method.Name}, 即将使用新方法 {info.DeclaringType}-{info.Name} 进行覆盖");
methods[a.type] = new FindAssetsMethodInfo()
{
obj = assembly.CreateInstance(t.Name),
method = info,
};
continue;
}
methods.Add(a.type, new FindAssetsMethodInfo()
{
obj = assembly.CreateInstance(t.Name),
method = info,
});
}
}
}
}
}
[MenuItem("Assets/在当前场景查找引用该资源的所有资源")]
private static void CurrentSceneFindAssetReference()
{
Init();
obj = Selection.activeObject;
if (obj == null)
{
Debug.LogWarning($"暂不支持文件夹的引用查找");
return;
}
Type type = obj.GetType();
Type p = type.BaseType;
Debug.Log($"当前资源类型:{type}", obj);
if (!methods.ContainsKey(type) && !methods.ContainsKey(p))
{
Debug.LogWarning($"不存在对该类型资源在当前场景中进行查询引用的方法实现!");
return;
}
bool notFindResult = true;
// 获取当前场景中的所有游戏对象(包括未激活的)
scene = EditorSceneManager.GetActiveScene();
GameObject[] allObjects = scene.GetRootGameObjects();
if (methods.TryGetValue(type, out FindAssetsMethodInfo info))
{
foreach (GameObject go in allObjects)
{
IList<Object> objs = info.method.Invoke(info.obj, new object[] { go, obj }) as IList<Object>;
if (objs != null && objs.Count > 0)
{
notFindResult = false;
foreach (Object obj in objs)
{
Debug.Log($"<color=yellow>当前场景中引用该物体的对象:{obj}, 引用的资源类型:{type.Name}</color>", obj);
}
}
}
}
else
{
Debug.LogWarning($"当前资源类型 {type} 查找方法未定义!");
}
if (notFindResult)
Debug.LogWarning($"当前场景中未查询到引用该资源的对象");
if (p == typeof(Object)) return;
notFindResult = true;
if (methods.TryGetValue(p, out info))
{
Debug.Log($"当前资源父类型:{p}");
foreach (GameObject go in allObjects)
{
IList<Object> objs = info.method.Invoke(info.obj, new object[] { go, obj }) as IList<Object>;
if (objs != null && objs.Count > 0)
{
foreach (Object obj in objs)
{
Debug.Log($"<color=yellow>当前场景中引用该物体的对象:{obj}, 引用的资源类型:{type.Name}</color>", obj);
}
notFindResult = false;
}
}
}
else
{
Debug.LogWarning($"当前资源父类型 {p} 查找方法未定义!");
}
if (notFindResult)
Debug.LogWarning($"当前场景中未查询到引用该资源的对象");
scene = default;
}
#endregion
}
/// <summary>
/// 纹理查找拓展
/// </summary>
class CurrentSceneFindTextureReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
const string mainTextureStr = "_MainTex";
[CurrentSceneFindAssetReferenceExpand(typeof(Texture))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
List<Object> objs = new List<Object>();
SpriteRenderer[] components = go.GetComponentsInChildren<SpriteRenderer>();
foreach (SpriteRenderer sprite in components)
{
if (sprite == null) continue;
if (sprite.sprite != null && sprite.sprite.texture == selectionActiveObject)
{
objs.Add(sprite.gameObject);
}
}
Renderer[] renderers = go.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
if (renderer == null) continue;
foreach (Material ma in renderer.sharedMaterials)
{
if (ma.HasTexture(mainTextureStr) && ma.mainTexture == selectionActiveObject)
{
objs.Add(renderer.gameObject);
}
}
}
Image[] images = go.GetComponentsInChildren<Image>();
foreach (Image image in images)
{
if (image == null) continue;
if (image.sprite != null && image.sprite.texture == selectionActiveObject)
{
objs.Add(image.gameObject);
}
}
return objs;
}
}
/// <summary>
/// 材质查找拓展
/// </summary>
class CurrentSceneFindMaterialReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
[CurrentSceneFindAssetReferenceExpand(typeof(Material))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
List<Object> objs = new List<Object>();
Renderer[] renderers = go.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
if (renderer == null) continue;
foreach (Material ma in renderer.sharedMaterials)
{
if (ma == selectionActiveObject)
{
objs.Add(renderer.gameObject);
}
}
}
return objs;
}
}
/// <summary>
/// 脚本查找拓展
/// </summary>
class CurrentSceneFindMonoScriptReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
[CurrentSceneFindAssetReferenceExpand(typeof(MonoScript))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
MonoScript script = selectionActiveObject as MonoScript;
List<Object> objs = new List<Object>();
MonoBehaviour[] monos = go.GetComponentsInChildren<MonoBehaviour>();
foreach (MonoBehaviour mono in monos)
{
if (mono == null) continue;
if (mono.GetType() == script.GetClass())
{
objs.Add(mono.gameObject);
}
}
return objs;
}
}
/// <summary>
/// 网格查找拓展
/// </summary>
class CurrentSceneFindMeshReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
[CurrentSceneFindAssetReferenceExpand(typeof(Mesh))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
List<Object> objs = new List<Object>();
MeshFilter[] meshes = go.GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter mesh in meshes)
{
if (mesh == null) continue;
if (mesh.sharedMesh == selectionActiveObject || mesh.sharedMesh.name.Contains(selectionActiveObject.name))
{
objs.Add(mesh.gameObject);
}
}
return objs;
}
}
/// <summary>
/// 预制体查找拓展
/// </summary>
class CurrentSceneFindGameObjectReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
private string findObjPath = null;
[CurrentSceneFindAssetReferenceExpand(typeof(GameObject))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
findObjPath = AssetDatabase.GetAssetPath(selectionActiveObject);
List<Object> objs = new List<Object>();
FindChild(go.transform, selectionActiveObject, objs);
return objs;
}
private void FindChild(Transform parent, Object selectionActiveObject, List<Object> objs)
{
if (parent.childCount < 1)
{
if (PrefabUtility.GetCorrespondingObjectFromOriginalSource<Object>(parent.gameObject) == selectionActiveObject ||
PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(parent.gameObject).CompareTo(findObjPath) == 0)
{
objs.Add(parent.gameObject);
}
}
else
{
foreach (Transform child in parent.transform)
{
FindChild(child, selectionActiveObject, objs);
}
if (PrefabUtility.GetCorrespondingObjectFromOriginalSource<Object>(parent.gameObject) == selectionActiveObject ||
PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(parent.gameObject).CompareTo(findObjPath) == 0)
{
objs.Add(parent.gameObject);
}
}
}
}
/// <summary>
/// 当前场景资源引用查找拓展特性
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
internal class CurrentSceneFindAssetReferenceExpandAttribute : Attribute
{
/// <summary>
/// 当前方法支持的查询的资源类型
/// </summary>
public Type type;
public CurrentSceneFindAssetReferenceExpandAttribute(Type type)
{
this.type = type;
}
}
/// <summary>
/// 当前场景资源引用查找接口
/// </summary>
internal interface ICurrentSceneFindAssetReferenceExpand
{
/// <summary>
///
/// </summary>
/// <param name="go"></param>
/// <param name="selectionActiveObject"></param>
/// <returns>存在引用的物体集合</returns>
IList<Object> FindAssets(GameObject go, Object selectionActiveObject);
}
/// <summary>
/// 资源查找方法缓存信息
/// </summary>
internal class FindAssetsMethodInfo
{
public object obj;
public MethodInfo method;
}
代码改进,不用协程,改用Task实现:
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Object = UnityEngine.Object;
/// <summary>
/// 查找资源引用工具
/// </summary>
public class FindReferencesTools
{
private const string FindTip = "未查询到引用该文件的资源";
private const string AssetsPath = "Assets/";
private const string EndsWithStr1 = ".meta";
private static bool findResult;
private static Object obj;
private static float currentProcess;
private static Dictionary<Type, FindAssetsMethodInfo> methods;
private static bool init = false;
private static string fileName;
private static string fileNameExtension;
private static StringBuilder sb;
private static Scene scene;
#region 查询Project中的资源引用
[MenuItem("Assets/查找引用该资源的所有资源")]
private static async void FindAssetReference()
{
findResult = true;
obj = Selection.activeObject;
string p = AssetDatabase.GetAssetPath(obj);
string guid = AssetDatabase.AssetPathToGUID(p);
Debug.Log($"当前文件所在路径:{p}", obj);
Debug.Log($"当前文件GUID:{guid}");
fileName = p;
fileNameExtension = p + ".meta";
sb = new StringBuilder();
await TraverseAllFile(guid, AssetsPath);
}
private static bool CheckReferenceInfo(string guid, string filePath)
{
return File.ReadAllText(filePath).Contains(guid);
}
private static async Task TraverseAllFile(string guid, string path)
{
await Task.Delay(1);
currentProcess = 0;
while (true)
{
currentProcess++;
string[] files = Directory.GetFiles(path);
string[] directorys = Directory.GetDirectories(path);
bool Cancel = EditorUtility.DisplayCancelableProgressBar($"正在查询对 {obj.name} 资产的所有引用", path, currentProcess / directorys.Length);
foreach (string dir in directorys)
{
await TraverseAllFile(guid, dir);
if (Cancel) break;
}
if (Cancel) break;
foreach (string f in files)
{
sb.Clear();
sb.Append(f);
sb.Replace('\\', '/');
string nf = sb.ToString();
if (nf.ToString().CompareTo(fileName) == 0 || nf.CompareTo(fileNameExtension) == 0) continue;
if (CheckReferenceInfo(guid, f))
{
//Debug.LogWarning($"存在引用----文件:{f}");
if (f.EndsWith(EndsWithStr1))
{
string newP = f.Substring(0, f.LastIndexOf('.'));
Debug.LogWarning($"存在引用----文件 <a href=\"{newP}\" line=\"1\">{newP}</a>", AssetDatabase.LoadAssetAtPath(newP, typeof(Object)));
}
else
Debug.LogWarning($"存在引用----文件 <a href=\"{f}\" line=\"1\">{f}</a>", AssetDatabase.LoadAssetAtPath(f, typeof(Object)));
findResult = false;
}
if (Cancel) break;
}
break;
}
EditorUtility.ClearProgressBar();
bool result = AssetsPath.CompareTo(path) == 0;
if (findResult && result)
Debug.LogWarning(FindTip);
if (result)
sb = null;
System.GC.Collect();
}
#endregion
#region 查询当前场景中的资源引用
private static void Init()
{
if (init) return;
init = true;
methods = new Dictionary<Type, FindAssetsMethodInfo>();
Assembly assembly = typeof(FindReferencesTools).Assembly;
Type[] types = assembly.GetTypes();
Type interfaceType = typeof(ICurrentSceneFindAssetReferenceExpand);
foreach (Type t in types)
{
if (interfaceType != t && interfaceType.IsAssignableFrom(t))
{
MethodInfo[] infos = t.GetMethods();
foreach (MethodInfo info in infos)
{
var a = info.GetCustomAttribute<CurrentSceneFindAssetReferenceExpandAttribute>();
if (a != null)
{
if (methods.ContainsKey(a.type))
{
Debug.LogWarning($"已存在对类型:{a.type} 的查找方法,方法名:{methods[a.type].method.DeclaringType}-{methods[a.type].method.Name}, 即将使用新方法 {info.DeclaringType}-{info.Name} 进行覆盖");
methods[a.type] = new FindAssetsMethodInfo()
{
obj = assembly.CreateInstance(t.Name),
method = info,
};
continue;
}
methods.Add(a.type, new FindAssetsMethodInfo()
{
obj = assembly.CreateInstance(t.Name),
method = info,
});
}
}
}
}
}
[MenuItem("Assets/在当前场景查找引用该资源的所有资源")]
private static void CurrentSceneFindAssetReference()
{
Init();
obj = Selection.activeObject;
if (obj == null)
{
Debug.LogWarning($"暂不支持文件夹的引用查找");
return;
}
Type type = obj.GetType();
Type p = type.BaseType;
Debug.Log($"当前资源类型:{type}", obj);
if (!methods.ContainsKey(type) && !methods.ContainsKey(p))
{
Debug.LogWarning($"不存在对该类型资源在当前场景中进行查询引用的方法实现!");
return;
}
bool notFindResult = true;
// 获取当前场景中的所有游戏对象(包括未激活的)
scene = EditorSceneManager.GetActiveScene();
GameObject[] allObjects = scene.GetRootGameObjects();
if (methods.TryGetValue(type, out FindAssetsMethodInfo info))
{
foreach (GameObject go in allObjects)
{
IList<Object> objs = info.method.Invoke(info.obj, new object[] { go, obj }) as IList<Object>;
if (objs != null && objs.Count > 0)
{
notFindResult = false;
foreach (Object obj in objs)
{
Debug.Log($"<color=yellow>当前场景中引用该物体的对象:{obj}, 引用的资源类型:{type.Name}</color>", obj);
}
}
}
}
else
{
Debug.LogWarning($"当前资源类型 {type} 查找方法未定义!");
}
if (notFindResult)
Debug.LogWarning($"当前场景中未查询到引用该资源的对象");
if (p == typeof(Object)) return;
notFindResult = true;
if (methods.TryGetValue(p, out info))
{
Debug.Log($"当前资源父类型:{p}");
foreach (GameObject go in allObjects)
{
IList<Object> objs = info.method.Invoke(info.obj, new object[] { go, obj }) as IList<Object>;
if (objs != null && objs.Count > 0)
{
foreach (Object obj in objs)
{
Debug.Log($"<color=yellow>当前场景中引用该物体的对象:{obj}, 引用的资源类型:{type.Name}</color>", obj);
}
notFindResult = false;
}
}
}
else
{
Debug.LogWarning($"当前资源父类型 {p} 查找方法未定义!");
}
if (notFindResult)
Debug.LogWarning($"当前场景中未查询到引用该资源的对象");
scene = default;
}
#endregion
}
/// <summary>
/// 纹理查找拓展
/// </summary>
class CurrentSceneFindTextureReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
const string mainTextureStr = "_MainTex";
[CurrentSceneFindAssetReferenceExpand(typeof(Texture))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
List<Object> objs = new List<Object>();
SpriteRenderer[] components = go.GetComponentsInChildren<SpriteRenderer>();
foreach (SpriteRenderer sprite in components)
{
if (sprite == null) continue;
if (sprite.sprite != null && sprite.sprite.texture == selectionActiveObject)
{
objs.Add(sprite.gameObject);
}
}
Renderer[] renderers = go.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
if (renderer == null) continue;
foreach (Material ma in renderer.sharedMaterials)
{
if (ma.mainTexture != null && ma.mainTexture == selectionActiveObject)
{
objs.Add(renderer.gameObject);
}
}
}
Image[] images = go.GetComponentsInChildren<Image>();
foreach (Image image in images)
{
if (image == null) continue;
if (image.sprite != null && image.sprite.texture == selectionActiveObject)
{
objs.Add(image.gameObject);
}
}
return objs;
}
}
/// <summary>
/// 材质查找拓展
/// </summary>
class CurrentSceneFindMaterialReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
[CurrentSceneFindAssetReferenceExpand(typeof(Material))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
List<Object> objs = new List<Object>();
Renderer[] renderers = go.GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
if (renderer == null) continue;
foreach (Material ma in renderer.sharedMaterials)
{
if (ma == selectionActiveObject)
{
objs.Add(renderer.gameObject);
}
}
}
return objs;
}
}
/// <summary>
/// 脚本查找拓展
/// </summary>
class CurrentSceneFindMonoScriptReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
[CurrentSceneFindAssetReferenceExpand(typeof(MonoScript))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
MonoScript script = selectionActiveObject as MonoScript;
List<Object> objs = new List<Object>();
MonoBehaviour[] monos = go.GetComponentsInChildren<MonoBehaviour>();
foreach (MonoBehaviour mono in monos)
{
if (mono == null) continue;
if (mono.GetType() == script.GetClass())
{
objs.Add(mono.gameObject);
}
}
return objs;
}
}
/// <summary>
/// 网格查找拓展
/// </summary>
class CurrentSceneFindMeshReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
[CurrentSceneFindAssetReferenceExpand(typeof(Mesh))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
List<Object> objs = new List<Object>();
MeshFilter[] meshes = go.GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter mesh in meshes)
{
if (mesh == null) continue;
if (mesh.sharedMesh == selectionActiveObject || mesh.sharedMesh.name.Contains(selectionActiveObject.name))
{
objs.Add(mesh.gameObject);
}
}
return objs;
}
}
/// <summary>
/// 预制体查找拓展
/// </summary>
class CurrentSceneFindGameObjectReferenceExpand : ICurrentSceneFindAssetReferenceExpand
{
private string findObjPath = null;
[CurrentSceneFindAssetReferenceExpand(typeof(GameObject))]
public IList<Object> FindAssets(GameObject go, Object selectionActiveObject)
{
findObjPath = AssetDatabase.GetAssetPath(selectionActiveObject);
List<Object> objs = new List<Object>();
FindChild(go.transform, selectionActiveObject, objs);
return objs;
}
private void FindChild(Transform parent, Object selectionActiveObject, List<Object> objs)
{
if (parent.childCount < 1)
{
if (PrefabUtility.GetCorrespondingObjectFromOriginalSource<Object>(parent.gameObject) == selectionActiveObject ||
PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(parent.gameObject).CompareTo(findObjPath) == 0)
{
objs.Add(parent.gameObject);
}
}
else
{
foreach (Transform child in parent.transform)
{
FindChild(child, selectionActiveObject, objs);
}
if (PrefabUtility.GetCorrespondingObjectFromOriginalSource<Object>(parent.gameObject) == selectionActiveObject ||
PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(parent.gameObject).CompareTo(findObjPath) == 0)
{
objs.Add(parent.gameObject);
}
}
}
}
/// <summary>
/// 当前场景资源引用查找拓展特性
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
internal class CurrentSceneFindAssetReferenceExpandAttribute : Attribute
{
/// <summary>
/// 当前方法支持的查询的资源类型
/// </summary>
public Type type;
public CurrentSceneFindAssetReferenceExpandAttribute(Type type)
{
this.type = type;
}
}
/// <summary>
/// 当前场景资源引用查找接口
/// </summary>
internal interface ICurrentSceneFindAssetReferenceExpand
{
/// <summary>
///
/// </summary>
/// <param name="go"></param>
/// <param name="selectionActiveObject"></param>
/// <returns>存在引用的物体集合</returns>
IList<Object> FindAssets(GameObject go, Object selectionActiveObject);
}
/// <summary>
/// 资源查找方法缓存信息
/// </summary>
internal class FindAssetsMethodInfo
{
public object obj;
public MethodInfo method;
}
更多推荐


所有评论(0)