できるようになること
フォルダ構造をラインで表して、ファイルがどこの階層にあるのかわかりやすくなる。
前置き
有料アセットにもあるが自分で作れば無料なので自分でつくった。
使い方
以下のコードをEditorフォルダに入れる。表示が変化しなときはUnity再起動。
ProjectFolderLines.cs
using UnityEditor;
using UnityEngine;
using System.Linq;
[InitializeOnLoad]
public static class ProjectFolderLines
{
static ProjectFolderLines()
{
EditorApplication.projectWindowItemOnGUI += OnProjectWindowItemOnGUI;
}
private static void OnProjectWindowItemOnGUI(string guid, Rect selectionRect)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
bool isFolder = AssetDatabase.IsValidFolder(path);
int depth = path.Count(f => f == '/') - "Assets".Count(f => f == '/');
// スプライトシートからのスプライトであるかどうかを判断
bool isMultiSprite = false;
TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
if (importer != null && importer.spriteImportMode == SpriteImportMode.Multiple)
{
isMultiSprite = true;
}
if (depth > 0)
{
DrawVerticalLines(selectionRect, depth, isFolder, isMultiSprite);
}
}
private static void DrawVerticalLines(Rect selectionRect, int depth, bool isFolder, bool isMultiSprite)
{
float indent = 14; // Unityのデフォルトのインデントサイズ
Handles.BeginGUI();
// フォルダとファイル、スプライトシートからのスプライトでオフセットを調整
float baseOffset = isFolder ? 7 : 7; // 通常のファイルやフォルダに対するオフセット
if (isMultiSprite)
{
baseOffset = 7; // スプライトシートからのスプライトに対するオフセット
}
for (int i = 1; i <= depth; i++)
{
float lineX = selectionRect.x - indent * i - baseOffset;
Handles.color = GetColorByDepth(depth - i + 1);
Vector2 startPoint = new Vector2(lineX, selectionRect.y);
Vector2 endPoint = new Vector2(lineX, selectionRect.yMax);
Handles.DrawLine(startPoint, endPoint);
}
Handles.EndGUI();
}
// 階層の深さに応じた色を取得するメソッド
private static Color GetColorByDepth(int depth)
{
switch (depth)
{
case 1:
return Color.red;
case 2:
return Color.green;
case 3:
return Color.blue;
case 4:
return Color.yellow;
case 5:
return Color.magenta;
case 6:
return Color.cyan;
case 7:
return Color.grey;
case 8:
return new Color(1f, 0.5f, 0f); // オレンジ
case 9:
return new Color(0.5f, 0f, 0.5f); // パープル
case 10:
return new Color(0f, 0.5f, 0f); // ダークグリーン
case 11:
return new Color(0.5f, 0.5f, 0f); // オリーブ
// 以下、必要に応じて他の階層の色を追加
default:
return new Color(0.5f, 0.5f, 0.5f, 0.2f); // デフォルトの色
}
}
}
HierarchyFolderLines.cs
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class HierarchyFolderLines
{
static HierarchyFolderLines()
{
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemOnGUI;
}
private static void OnHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
{
GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (obj != null)
{
int depth = GetDepth(obj.transform);
DrawVerticalLines(selectionRect, depth);
}
}
private static int GetDepth(Transform transform)
{
int depth = 0;
while (transform.parent != null)
{
depth++;
transform = transform.parent;
}
return depth; // "Assets"の階層を含まないので、ここでは調整不要
}
private static void DrawVerticalLines(Rect selectionRect, int depth)
{
float indentWidth = 14f; // Unityのデフォルトのインデントサイズ
float baseIndent = 14f; // 基準となるインデント
float lineWidth = 1f; // 線の幅
Handles.BeginGUI();
for (int i = 0; i < depth; i++)
{
float indent = baseIndent + (indentWidth * i) + (indentWidth / 2f); // インデントの調節
float lineX = selectionRect.x - indent;
// 色を親から決定する
Color lineColor = GetColorByDepth(depth - i,0.2f);
Handles.DrawSolidRectangleWithOutline(new Rect(lineX, selectionRect.y, lineWidth, selectionRect.height), lineColor, lineColor);
}
Handles.EndGUI();
}
// 階層の深さに応じた色を取得するメソッド(アルファ値付き)
private static Color GetColorByDepth(int depth, float alpha = 1.0f)
{
Color color;
switch (depth)
{
case 1:
color = Color.red;
break;
case 2:
color = Color.green;
break;
case 3:
color = Color.blue;
break;
case 4:
color = Color.yellow;
break;
case 5:
color = Color.magenta;
break;
case 6:
color = Color.cyan;
break;
case 7:
color = Color.grey;
break;
case 8:
color = new Color(1f, 0.5f, 0f); // オレンジ
break;
case 9:
color = new Color(0.5f, 0f, 0.5f); // パープル
break;
case 10:
color = new Color(0f, 0.5f, 0f); // ダークグリーン
break;
case 11:
color = new Color(0.5f, 0.5f, 0f); // オリーブ
break;
default:
color = new Color(0.5f, 0.5f, 0.5f); // デフォルトの色
break;
}
return new Color(color.r, color.g, color.b, alpha);
}
}
これで見やすくなるね。やったね。
202406 追記
HierarchyとProjectの名前が逆になっていたので修正
もっとみやすくProjectフォルダにラインと同様の色を設定できるスクリプト追加
適応後
ProjectFolderColors.cs
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
public static class ColoredProjectView
{
const string MenuPath = "NXLab/ColoredProjectView";
const string PrefKey = "NXLab_ColoredProjectView_Enabled";
[MenuItem(MenuPath)]
static void ToggleEnabled()
{
bool isEnabled = !Menu.GetChecked(MenuPath);
Menu.SetChecked(MenuPath, isEnabled);
EditorPrefs.SetBool(PrefKey, isEnabled);
EditorApplication.RepaintProjectWindow();
}
[InitializeOnLoadMethod]
static void Initialize()
{
SetEvent();
bool isEnabled = EditorPrefs.GetBool(PrefKey, true); // 初期値をtrueに設定
Menu.SetChecked(MenuPath, isEnabled);
}
static void SetEvent()
{
EditorApplication.projectWindowItemOnGUI += OnGUI;
}
static void OnGUI(string guid, Rect selectionRect)
{
if (!Menu.GetChecked(MenuPath))
{
return;
}
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
int depth = assetPath.Split('/').Length - 1;
Color colorToUse = GetColorByDepth(depth);
// アルファ値を設定して色を適用
colorToUse.a = GetAlphaByDepth(depth);
EditorGUI.DrawRect(selectionRect, colorToUse);
}
private static Color GetColorByDepth(int depth)
{
// 指定された階層に基づいて色を返す
switch (depth)
{
case 1: return Color.red;
case 2: return Color.green;
case 3: return Color.blue;
case 4: return Color.yellow;
case 5: return Color.magenta;
case 6: return Color.cyan;
case 7: return Color.grey;
case 8: return new Color(1f, 0.5f, 0f); // オレンジ
case 9: return new Color(0.5f, 0f, 0.5f); // パープル
case 10: return new Color(0f, 0.5f, 0f); // ダークグリーン
case 11: return new Color(0.5f, 0.5f, 0f); // オリーブ
default: return new Color(0.5f, 0.5f, 0.5f); // デフォルトの色
}
}
private static float GetAlphaByDepth(int depth)
{
// 階層の深さに応じてアルファ値を補間する
// 例:最深部でアルファ値を最も低くする
const float maxDepth = 10f; // この深さ以降はアルファ値が最小になる
const float minAlpha = 0.01f; // アルファ値の最小値
const float maxAlpha = 0.05f; // アルファ値の最大値
// 階層の深さに基づいてアルファ値を計算する
float alpha = maxAlpha - ((depth - 1) / maxDepth) * (maxAlpha - minAlpha);
return Mathf.Clamp(alpha, minAlpha, maxAlpha);
}
}
#endif