# AssetsReferenceTool
**Repository Path**: amiemie/AssetsReferenceTool
## Basic Information
- **Project Name**: AssetsReferenceTool
- **Description**: 资源引用工具
- **Primary Language**: C#
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-11-04
- **Last Updated**: 2021-11-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# AssetsReferenceTool
资源引用工具
### 一 功能简述
包含两个主要功能
* 查找某预制体资源引用了那些贴图资源
* 查找某贴图资源被那些预制体引用,并定位预制体到检视面板
### 二 设计思路
* 集成工具面板,包含了多个工具,所以需要一个基础的工具面板类BaseAssetTool,集成工具面板包含一个基础工具类列表,定义集成面板包含的工具列表BaseAssetTool[] toolArray,各个工具类按照需求继承基础工具类,再分别扩展自己需要的功能
* 资源工具面板
* 资源工具基类,实现基础方法,需要子类重写的虚方法等
### 三 实现代码
AssetToolsWindow 资源工具面板
```csharp
using UnityEngine;
using UnityEditor;
namespace EditorAssetTools {
///
/// 编辑器多工具集成窗口
///
public class EditorAssetToolsWindow : EditorWindow {
[MenuItem("Tools/编辑器资源工具")]
static void OpenInProjectView() {
EditorAssetToolsWindow.OpenToolsWindow(); //编辑器资源工具入口
}
int selectToolIndex = -1; //选中的工具索引
string[] toolDisplayArray; //工具的显示名称
BaseAssetTool[] toolArray = new BaseAssetTool[] { //工具列表,这里只分析引用查找工具
//new ModifyNameAssetTool(),
new ReferenceSearchAssetTool(),
//new TextureCheckTool(),
//new TransparentGraphicPrefabCheckTool(),
};
static void OpenToolsWindow() { //打开集成工具窗口,包含工具列表的工具
if(Application.isPlaying) {
Debug.LogError("不允许在运行状态下打开资源工具窗口");
return;
}
//打开编辑器窗口,1false代表非浮动窗口,2名称,3false代表聚焦,第一次打开默认聚焦
var window = EditorWindow.GetWindow(false, "资源工具", false);
EditorWindow.FocusWindowIfItsOpen();//第一次打开聚焦
window.Show();//显示面板
}
//OnEnable时调用
void OnEnable() {
toolDisplayArray = new string[toolArray.Length];//创建工具名称数组
for(int idx = 0; idx < toolArray.Length; ++idx) { //遍历工具列表
BaseAssetTool tool = toolArray[idx];//工具
tool.toolsWindow = this;
tool.DoInit(); //初始化工具,主要是初始化资源路径列表
toolDisplayArray[idx] = tool.Name;//保存工具名称
}
if(selectToolIndex < 0) SelectTool(0);//默认选第一个工具
Selection.selectionChanged += OnSelectChange;//当前所选项发生更改时触发的委托回调 OnSelectChange
}
void OnDisable() {
foreach (var tool in toolArray) tool.DoDestroy(); //销毁各个工具实例
Selection.selectionChanged -= OnSelectChange;//取消注册委托侦听
}
void SelectTool(int index) { //选择工具
if(selectToolIndex == index) return;//相同不进行处理
selectToolIndex = index;//更新index
toolArray[selectToolIndex].DoShow();//选中的工具调用自身的DoShow方法
}
void OnGUI() { //绘制界面
if (GUILayout.Button("-->说明文档<--", EditorStyles.toolbarButton)) { //添加工具栏的单击按钮
Application.OpenURL("url");
}
//创建一个工具栏,1所选按钮索引,2按钮的名称 列表,3按钮样式,return 选中的索引
int selectIndex = GUILayout.Toolbar(selectToolIndex, toolDisplayArray, EditorStyles.toolbarButton);
if(selectIndex != selectToolIndex) { //工具栏选中索引和当前的不一致
SelectTool(selectIndex);//选中当前索引的工具
}
EditorGUILayout.Space();//在上一个控件和下一个控件之间留出一个小空间
toolArray[selectToolIndex].OnGUI();//调用选中工具的OnGUI方法
}
void Update() {
if(Application.isPlaying) { //运行则不处理
base.Close();
return;
}
foreach (var tool in toolArray) tool.Update();//各个工具调用更新方法
}
void OnSelectChange() { //选中的内容发生变动
toolArray[selectToolIndex].OnSelectChange();//调用当前选中的工具的OnSelectChange
base.Repaint();//重绘GUI
}
}
}
```
### BaseAssetTool 工具基础类
包含工具基础的功能和各个工具类需要重写的虚方法
```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using UnityEditor;
namespace EditorAssetTools {
public abstract class BaseAssetTool {
EditorAssetToolsWindow tools_window;
protected List allAssetPath = new List();//所有资源的路径
protected string selectAssetPath = null;//选中资源的路径
GameObject sceneRootGo;//预制体对象在场景的挂载节点
GameObject sceneUIRootGo;//UI预制体对象在场景的挂载节点
Dictionary prefabInstanceRecordDict = new Dictionary();//实例化的预制体字典
readonly string[] defaultTargetDirectoryArray = new string[] { //默认的文件夹列表
"选择预设目录",
"Assets/Prefabs/UI",
};
protected string targetDirectory { get; private set; }
public EditorAssetToolsWindow toolsWindow {
get {return tools_window; }
set {tools_window = value; }
}
public virtual void DoInit() {
allAssetPath.AddRange(AssetDatabase.GetAllAssetPaths()); //获取项目中所有的资源路径并把路径添加到allAssetPath列表尾部
targetDirectory = "Assets";
}
public virtual void DoDestroy() { //销毁方法
if(sceneRootGo != null) {
GameObject.DestroyImmediate(sceneRootGo);
sceneRootGo = null;
}
if(sceneUIRootGo != null) {
GameObject.DestroyImmediate(sceneUIRootGo);
sceneUIRootGo = null;
}
prefabInstanceRecordDict.Clear();
allAssetPath.Clear();
}
//定义需要子类重写的虚方法或实现的抽象方法
public virtual void DoShow() {} //界面OnShow
public virtual void OnSelectChange() {} //选中项发生变化,委托
public abstract string Name { get; } //抽象属性,面板名称
public abstract void OnGUI();//需要实现的OnGUI方法
public virtual void Update () {
selectAssetPath = AssetDatabase.GetAssetPath(Selection.activeObject);//更新选中项的资源路径
}
protected void DrawTargetDirectoryOnGUI(string label) {
using (new EditorGUILayout.HorizontalScope()) { //创建一个新的 HorizontalScope 并开始相应的水平组,滚动视图
targetDirectory = EditorGUILayout.TextField(label, targetDirectory);//目标文件夹
int index = EditorGUILayout.Popup(0, defaultTargetDirectoryArray, GUILayout.Width(80));//
if(index >= 1) {
targetDirectory = defaultTargetDirectoryArray[index];
}
if (!AssetDatabase.IsValidFolder(targetDirectory)) { //文件夹不是有效的文件夹
Color lastColumn = GUI.contentColor;
GUI.contentColor = Color.red;
EditorGUILayout.LabelField("目录无效!!!", GUILayout.Width(100));
GUI.contentColor = lastColumn;
}
}
}
//获取预制体对象在场景中的挂载节点,bool是否UI类型的
protected GameObject GetSceneRootGo(bool isUI) {
if (!isUI) { //不是UI
if(sceneRootGo == null) { //sceneRootGo场景挂载节点
sceneRootGo = new GameObject(this.Name);
}
return sceneRootGo;
}
if(sceneUIRootGo == null) {
sceneUIRootGo = new GameObject(this.Name + "_UI"); //创建一个新的挂载节点
Canvas sceneCanvas = GameObject.FindObjectOfType