Unity自定义窗口中显示文件夹的结构
假如我想在自定义窗口中显示文件夹的结构,并且可以用鼠标选择对应的文件。如下图所示,文件夹的结构我显示在了Inspector里,鼠标可以进行选择操作。

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
[CustomEditor(typeof(UnityEditor.DefaultAsset))]
public class FolderInspector : Editor
{
class Data//数据结构体
{
public bool isSelected = false;//是否被选择
public int indent = 0;//层级
public GUIContent content;//GUI内容
public string assetPath;//资源路径
public List<Data> childs = new List<Data>();//子节点容器
}
Data data;//储存数据
Data selectData;//选择的数据
void OnEnable()//点击project中的文件夹时才会调用
{
// AssetDatabase.GetAssetPath(target)通过选择的物体获取真实物体
if (Directory.Exists(AssetDatabase.GetAssetPath(target)))//target指当前被检视的Object
{
data = new Data();
// Selection.activeObject返回当前选择的真实物体,包括预制体和不可修改的物体
LoadFiles(data, AssetDatabase.GetAssetPath(Selection.activeObject));
}
Debug.Log("点击了文件夹");
}
public override void OnInspectorGUI()//重绘制检视面板
{
if (Directory.Exists(AssetDatabase.GetAssetPath(target)))
{
GUI.enabled = true;
EditorGUIUtility.SetIconSize(Vector2.one * 16f);//设置GUIContent界面内容图标的size
DrawData(data);//绘制数据
}
}
void LoadFiles(Data data, string currentPath, int indent = 0)//根据路径加载数据
{
GUIContent content = GetGUIContent(currentPath);//根据路径获取GUIContent(界面内容)
if (content != null)//数据构造
{
data.indent = indent;
data.content = content;
data.assetPath = currentPath;
}
foreach (var path in Directory.GetFiles(currentPath))//Directory.GetFiles返回指定目录中的文件名称
{
content = GetGUIContent(path);
if (content != null)
{
Data child = new Data();
child.indent = indent + 1;
child.content = content;
child.assetPath = path;
data.childs.Add(child);//把此文件夹下所有子节点加入到容器
}
}
foreach (var path in Directory.GetDirectories(currentPath))//Directory.GetDirectories获取指定目录中子目录的名称
{
Data childDir = new Data();
data.childs.Add(childDir);//把此文件夹下所有子节点加入到容器
LoadFiles(childDir, path, indent + 1);//递归加载子目录文件
}
}
void DrawData(Data data)//递归法绘制树状节点数据
{
if (data.content != null)
{
EditorGUI.indentLevel = data.indent;
DrawGUIData(data);//绘制GUI数据
}
for (int i = 0; i < data.childs.Count; i++)
{
Data child = data.childs[i];
if (child.content != null)
{
EditorGUI.indentLevel = child.indent;
if (child.childs.Count > 0)
DrawData(child);//递归
else
DrawGUIData(child);//绘制GUI数据
}
}
}
void DrawGUIData(Data data)//绘制GUI数据
{
GUIStyle style = "Label";
Rect rt = GUILayoutUtility.GetRect(data.content, style);
if (data.isSelected)
{
EditorGUI.DrawRect(rt, Color.green);//选中节点时绘制带颜色的窗口
}
rt.x += (16 * EditorGUI.indentLevel);//子节点相对父节点的缩进距离
if (GUI.Button(rt, data.content, style))//在窗口位置绘制一个按钮,显示内容为GUIContent,形式为GUIStyle
{
if (selectData != null)
{
selectData.isSelected = false;
}
data.isSelected = true;
selectData = data;
Debug.Log(data.assetPath);
}
}
GUIContent GetGUIContent(string path)//根据路径获取GUIContent(界面内容)
{
//加载资源
Object asset = AssetDatabase.LoadAssetAtPath(path, typeof(Object));
if (asset)
{//返回GUIcontent(界面内容)
return new GUIContent(asset.name, AssetDatabase.GetCachedIcon(path));//根据路径检索图标
}
return null;
}
}

浙公网安备 33010602011771号