Unity 查詢unity內建資源的工具
阿新 • • 發佈:2019-01-25
大致步驟:
1、找到Unity所有預設體和材質資源
2、拿到這些資源的依賴檔案
3、找到所有 依賴檔案裡的 Texture Shader Material Sprite
3.1、 拿到依賴檔案裡的預設體 加載出來 遍歷元件
3.2、 拿到依賴檔案裡的Material 加載出來 檢視shader 和貼圖
3.5 、 Texture 可能在RawImage元件裡 可能在Material元件裡
3.6 、Shader只可能在Materai裡
3.7 、Sprite在Image元件裡
4、AssetDatabase.GetAssetPath(Object) 拿到這個資源的路徑
5、如果這個路徑包含“builtin” 說明這個資源是unity內建的
程式碼:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.Editor.build
{
class FindBuildinResources : EditorWindow
{
[MenuItem("Tools/檢查/檢查buildin資源")]
public static void FindResource()
{
GetWindow<FindBuildinResources>().Show();
GetBuildinResource();
}
private Vector3 scrollPos = Vector3.zero;
private static Dictionary<UnityEngine.Object, Node> res = new Dictionary<UnityEngine.Object, Node>();
private const string shader = "shader";
private const string texture = "texture";
private const string material = "material";
private const string sprite = "sprite";
private const string prefab = "prefab";
private const string renderer = "renderer";
private const string image = "image";
private const string builtin = "builtin";
/// <summary>
/// 載入 buildin資源
/// </summary>
private static void GetBuildinResource()
{
res.Clear();
string path = "Assets/";
var allfiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).Where(
s => s.EndsWith("mat")
|| s.EndsWith("prefab")
).ToArray();
foreach (var item in allfiles)
{
if (item.EndsWith("prefab"))
{
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(item);
if (go)
{
#region 找到prefab裡的 buildin shader & material & texture
Renderer[] renders = go.GetComponentsInChildren<Renderer>(true);
foreach (var render in renders)
{
foreach (var mat in render.sharedMaterials)
{
if (!mat) continue;
//判斷材質是不是用的builtin的
if (AssetDatabase.GetAssetPath(mat).Contains(builtin))
{
Node n;
if (res.Keys.Contains(go)) n = res[go];
else
{
n = new Node(go, prefab);
res.Add(go, n);
}
n.Add(render, renderer).Add(mat, material);
}
//判斷shader是不是builtin的
if (AssetDatabase.GetAssetPath(mat.shader).Contains(builtin))
{
Node n;
if (res.Keys.Contains(go)) n = res[go];
else
{
n = new Node(go, prefab);
res.Add(go, n);
}
n.Add(render, renderer).Add(mat, material).Add(mat.shader, shader);
}
//判斷shader用的貼圖是不是用的builtin的
for (int i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++)
{
if (ShaderUtil.GetPropertyType(mat.shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
{
string propertyname = ShaderUtil.GetPropertyName(mat.shader, i);
Texture t = mat.GetTexture(propertyname);
if (t && AssetDatabase.GetAssetPath(t).Contains(builtin))
{
Node n;
if (res.Keys.Contains(go)) n = res[go];
else
{
n = new Node(go, prefab);
res.Add(go, n);
}
n.Add(render, renderer).Add(mat, material).Add(t, texture);
}
}
}
}
}
#endregion
#region 找到prefab裡的 buildin Sprite
Image[] images = go.GetComponentsInChildren<Image>(true);
foreach (var img in images)
{
if (AssetDatabase.GetAssetPath(img.sprite).Contains(builtin))
{
Node n;
if (res.Keys.Contains(go)) n = res[go];
else
{
n = new Node(go, prefab);
res.Add(go, n);
}
n.Add(img, "image").Add(img.sprite, sprite);
}
}
#endregion
#region 找到prefab 裡的Texture
RawImage[] rawimgs = go.GetComponentsInChildren<RawImage>(true);
foreach (var rawimg in rawimgs)
{
if (rawimg.texture && AssetDatabase.GetAssetPath(rawimg.texture).Contains(builtin))
{
Node n;
if (res.Keys.Contains(go)) n = res[go];
else
{
n = new Node(go, prefab);
res.Add(go, n);
}
n.Add(rawimg, "rawimage").Add(rawimg.texture, texture);
}
}
#endregion
}
}
else if (item.EndsWith("mat"))
{
#region 找到material裡的 shader
Material mt = AssetDatabase.LoadAssetAtPath<Material>(item);
if (!mt) continue;
if (AssetDatabase.GetAssetPath(mt.shader).Contains(builtin))
{
Node n;
if (res.Keys.Contains(mt)) n = res[mt];
else
{
n = new Node(mt, material);
res.Add(mt, n);
}
n.Add(mt.shader, shader);
}
#endregion
#region 找到material裡的 texutre
for (int i = 0; i < ShaderUtil.GetPropertyCount(mt.shader); i++)
{
if (ShaderUtil.GetPropertyType(mt.shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
{
string propertyname = ShaderUtil.GetPropertyName(mt.shader, i);
Texture t = mt.GetTexture(propertyname);
if (t && AssetDatabase.GetAssetPath(t).Contains(builtin))
{
Node n;
if (res.Keys.Contains(mt)) n = res[mt];
else
{
n = new Node(mt, material);
res.Add(mt, n);
}
n.Add(t, sprite);
}
}
}
#endregion
}
}
EditorUtility.DisplayDialog("", "就緒", "OK");
}
/// <summary>
/// 將standard 替換成Mobile Diffuse
/// </summary>
private static void ReplaceStandardToDiffuse()
{
Shader sd = Shader.Find("Standard");
Shader diffuse_sd = Shader.Find("Mobile/Diffuse");
int count = 0;
foreach (var item in res.Values)
{
TransforNode(item, (s) =>
{
if (s.des == material)
{
Material mt = s.content as Material;
if (mt && mt.shader == sd)
{
mt.shader = diffuse_sd;
count++;
}
}
});
}
EditorUtility.DisplayDialog("結果", "替換了" + count + "個Standard shader", "OK");
if (count != 0)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
GetBuildinResource();
}
}
/// <summary>
/// 將buildin shader 替換成本地shader
/// </summary>
private void ReplaceBuildinToLocal()
{
int count = 0;
foreach (var item in res.Values)
{
TransforNode(item, (s) =>
{
if (s.des == material)
{
Material mt = s.content as Material;
if (mt)
{
mt.shader = Shader.Find(mt.shader.name);
count++;
}
}
});
}
EditorUtility.DisplayDialog("結果", "替換了" + count + "個buildin shader", "OK");
if (count != 0)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
GetBuildinResource();
}
}
/// <summary>
/// 替換預設材質
/// </summary>
private void ReplaceDefaultMaterial()
{
string materialName = "Default-Material";
string[] x = Directory.GetFiles("Assets/Resources/", materialName + ".mat", SearchOption.AllDirectories);
if (x.Length == 0)
{
EditorUtility.DisplayDialog("提示", "Resource/misc/下沒有" + materialName + "!!!", "OK");
return;
}
Material defaultMaterial = AssetDatabase.LoadAssetAtPath<Material>(x[0]);
int count = 0;
foreach (var item in res.Values)
{
TransforNode(item, (s) =>
{
if (s.des == renderer)
{
Renderer render = s.content as Renderer;
if (render)
{
Material[] mats = render.sharedMaterials;
for (int i = 0; i < mats.Length; i++)
{
if (mats[i].name == materialName)
{
Material mt = defaultMaterial as Material;
if (mt)
{
mats[i] = mt;
count++;
}
}
}
render.sharedMaterials = mats;
}
}
});
}
EditorUtility.DisplayDialog("提示", "替換了" + count + "個" + materialName, "OK");
if (count != 0)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
GetBuildinResource();
}
}
/// <summary>
/// 移除使用預設材質的ParticleSystem元件
/// </summary>
private void RemoveParticleSystemWithDefaultParticle()
{
int count = 0;
foreach (var item in res.Values)
{
TransforNode(item, (s) =>
{
if (s.des == renderer)
{
Renderer render = s.content as Renderer;
if (render)
{
Material[] mats = render.sharedMaterials;
for (int i = 0; i < mats.Length; i++)
{
if (mats[i].name == "Default-Particle")
{
ParticleSystem ps = render.GetComponent<ParticleSystem>();
if (ps)
{
render.materials = new Material[] { };
DestroyImmediate(ps, true);
EditorUtility.SetDirty(render.gameObject);
count++;
break;
}
}
}
}
}
});
}
EditorUtility.DisplayDialog("提示", "Remove" + count + "個ParticleSystem元件", "OK");
if (count != 0)
{
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
GetBuildinResource();
}
}
private void OnGUI()
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("將所有Standard shader 替換成MobileDiffuse ", GUILayout.Width(400), GUILayout.Height(50))) ReplaceStandardToDiffuse();
if (GUILayout.Button("將所有buildin shader 替換成本地shader ", GUILayout.Width(400), GUILayout.Height(50))) ReplaceBuildinToLocal();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("替換所有Default Material", GUILayout.Width(400), GUILayout.Height(50))) ReplaceDefaultMaterial();
if (GUILayout.Button("移除所有帶Default Particle的ParticleSystem元件", GUILayout.Width(400), GUILayout.Height(50))) RemoveParticleSystemWithDefaultParticle();
EditorGUILayout.EndHorizontal();
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, false, true, GUILayout.Width(850));
EditorGUILayout.BeginVertical();
foreach (var item in res.Keys)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.ObjectField(item, item.GetType(), true, GUILayout.Width(200));
TransforNode(res[item]);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
EditorGUILayout.EndScrollView();
}
/// <summary>
/// 遍歷顯示
/// </summary>
/// <param name="n"></param>
private static void TransforNode(Node n)
{
EditorGUILayout.BeginVertical();
foreach (var item in n.next.Values)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.ObjectField(item.content, item.content.GetType(), true, GUILayout.Width(200));
TransforNode(item);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
}
/// <summary>
/// 遍歷 操作
/// </summary>
/// <param name="n"></param>
/// <param name="a"></param>
private static void TransforNode(Node n, Action<Node> a)
{
a(n);
foreach (var item in n.next.Values)
{
a(item);
TransforNode(item, a);
}
}
}
public class Node
{
public UnityEngine.Object content;
public string des;
public Dictionary<UnityEngine.Object, Node> next;
public Node Add(UnityEngine.Object obj, string type)
{
if (!next.Keys.Contains(obj))
{
Node no = new Node(obj, type);
next.Add(obj, no);
return no;
}
return next[obj];
}
public Node(UnityEngine.Object content, string des)
{
this.content = content;
this.des = des;
next = new Dictionary<UnityEngine.Object, Node>();
}
public void TransforNode(Action<Node> a)
{
a(this);
foreach (var item in next.Values)
{
a(item);
TransforNode(a);
}
}
}
}