废话少说,直接上代码。
using UnityEditor;
using UnityEngine;
public class FindDependencies : MonoBehaviour
{
static bool m_bIsSaveFile = false;
static TextWriteHelper m_szMaterialList = new TextWriteHelper();
static TextWriteHelper m_szPrefabList = new TextWriteHelper();
[MenuItem("Assets/FindImageDependencies")]
static void FindDepend()
{
m_szMaterialList.ClearData();
string imagePath = GetObjPath(); // "Assets/Path/To/Your/Image.png";
string[] guids = AssetDatabase.FindAssets("t:Material");
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
Material material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
if (material != null && HasTexture(material, imagePath))
{
Debug.Log(string.Format("Material referencing the image: {0}, and path = {1}", material.name, assetPath));
//m_szMaterialList.AddContent(string.Format("Material referencing the image: {0}, and path = {1}", material.name, assetPath));
FindPrefab(assetPath);
}
}
if (m_bIsSaveFile)
{
m_szMaterialList.SaveFile("MaterialReferenceList");
m_szPrefabList.SaveFile("PrefabReferenceList");
}
}
static string GetObjPath()
{
string path = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
return path;
}
static bool HasTexture(Material material, string texturePath)
{
SerializedObject serializedMaterial = new SerializedObject(material);
SerializedProperty texturesProperty = serializedMaterial.FindProperty("m_SavedProperties.m_TexEnvs");
for (int i = 0; i < texturesProperty.arraySize; i++)
{
SerializedProperty textureProperty = texturesProperty.GetArrayElementAtIndex(i);
SerializedProperty textureValueProperty = textureProperty.FindPropertyRelative("second.m_Texture");
if (textureValueProperty != null)
{
Texture texture = textureValueProperty.objectReferenceValue as Texture;
if (texture != null && AssetDatabase.GetAssetPath(texture) == texturePath)
{
return true;
}
}
}
return false;
}
static void FindPrefab(string materialPath)
{
//string materialPath = "Assets/Path/To/Your/Material.mat";
string[] guids = AssetDatabase.FindAssets("t:Prefab");
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
if (prefab != null && HasMaterialReference(prefab, materialPath))
{
Debug.Log(string.Format("Prefab referencing the material: {0},and prefab path ={1} ", prefab.name, assetPath));
//m_szPrefabList.AddContent(string.Format("Prefab referencing the material: {0},and prefab path ={1} ", prefab.name, assetPath));
}
}
}
static bool HasMaterialReference(GameObject gameObject, string materialPath)
{
Renderer[] renderers = gameObject.GetComponentsInChildren<Renderer>(true);
foreach (Renderer renderer in renderers)
{
foreach (Material material in renderer.sharedMaterials)
{
if (material != null && AssetDatabase.GetAssetPath(material) == materialPath)
{
return true;
}
}
}
return false;
}
}
上述代码中,我们首先使用AssetDatabase.FindAssets
方法通过过滤类型("t:Material")获取所有材质球的GUID。然后遍历每个GUID,加载对应的材质球,判断该材质球是否引用了指定的图片。我们定义了一个辅助方法HasTexture
来检查材质球中的纹理是否引用了目标图片,通过检查SerializedProperty来判断纹理是否匹配。
上述代码中,我们首先使用AssetDatabase.FindAssets
方法通过过滤类型("t:Prefab")获取所有预设的GUID。然后遍历每个GUID,加载对应的预设,并判断该预设是否引用了指定的材质球。我们定义了一个辅助方法HasMaterialReference
来检查预设及其子物体的渲染组件是否使用了目标材质球,通过遍历渲染组件的sharedMaterials
数组来进行匹配。
综上所诉,我们也可以通过相似的方式去查找其他类型的资源引用。好了大功告成。。。