在做项目时遇到了个问题,所以有了下面的内容。
问题:已经修改了某个零件模型,想重新替换原零件模型,但原零件模型在场景中被部分不同的脚本引用了,一个个找??会死人的。所以就想到了把引用了该零件的脚本遍历输出它的名字就好了呀喂。
不知道还有什么方式,欢迎评论了喂。
FindSpecifiedEditor.cs
using UnityEngine;
using UnityEditor;
public class FindSpecifiedEditor
{
private static GameObject targetObj;
//扩展Hierarchy面板右键弹出菜单
[MenuItem("GameObject/我的/找茬", priority = 0)]
static void CheckQuoteCurrentObj()
{
Debug.Log("正在查找");
FindSpecifiedGameObj.BeginCheck(targetObj);
}
[MenuItem("GameObject/我的/其他测试", priority = 0)]
static void Test()
{
Debug.Log("其他测试");
}
[InitializeOnLoadMethod]
static void StartInitializeOnLoadMethod()
{
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
}
static void OnHierarchyGUI(int instanceID, Rect selectionRect)
{
if (Event.current != null && selectionRect.Contains(Event.current.mousePosition)
&& Event.current.button == 1 && Event.current.type == EventType.MouseUp)
{
GameObject selectedGameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (selectedGameObject)
{
targetObj = selectedGameObject;
}
}
}
}
FindSpecifiedGameObj.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public class FindSpecifiedGameObj
{
//要查找的物体
private static GameObject targetObj;
public static void BeginCheck(GameObject _targetObj)
{
targetObj = _targetObj;
List<GameObject> roots = GetAllSceneObjectsWithInactive();
Dictionary<string, GameObject> dic = new Dictionary<string, GameObject>();
foreach (GameObject item in roots)
{
GetCompent(item);
}
}
private static void GetCompent(GameObject gameObject)
{
Component[] components = gameObject.GetComponentsInChildren<Component>();
foreach (var item in components)
{
GetPropertiesInCompent(item);
}
}
private static void GetPropertiesInCompent(Component item)
{
if (item.gameObject == targetObj)
{
return;
}
List<PropertyInfo> properties = item.GetType().GetProperties().Where(p => p.PropertyType.IsPublic
&& !p.PropertyType.IsValueType && p.PropertyType != typeof(Component)).ToList<PropertyInfo>();
foreach (var propertyItem in properties)
{
var value = propertyItem.GetValue(item, null);
if (value != null)
{
if (value == (object)targetObj)
{
Debug.Log("找到名称为下列的物体");
Debug.Log(item.gameObject.name);
}
}
}
GetFieldsInCompent(item);
}
private static void GetFieldsInCompent(Component item)
{
List<FieldInfo> fields = item.GetType().GetFields().Where(p => p.FieldType.IsPublic && !p.FieldType.IsValueType).ToList<FieldInfo>();
foreach (var fieldItem in fields)
{
var value = fieldItem.GetValue(item);
if (value != null)
{
if (value == (object)targetObj)
{
Debug.Log("找到名称为下列的物体:");
Debug.Log(item.gameObject.name);
}
}
}
}
//查找所有Hierarchy面板中的物体(包括禁用的)
private static List<GameObject> GetAllSceneObjectsWithInactive()
{
var allTransforms = Resources.FindObjectsOfTypeAll(typeof(Transform));
var previousSelection = Selection.objects;
Selection.objects = allTransforms.Cast<Transform>()
.Where(x => x != null)
.Select(x => x.gameObject)
//如果你只想获取所有在Hierarchy中被禁用的物体,反注释下面代码
//.Where(x => x != null && !x.activeInHierarchy)
.Cast<UnityEngine.Object>().ToArray();
var selectedTransforms = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
Selection.objects = previousSelection;
return selectedTransforms.Select(tr => tr.gameObject).ToList();
}
}
效果:
被多物体引用混球:
在混球上鼠标右键选择找茬:
输出: