Added support to scan prefabs

This commit is contained in:
Anders Ejlersen 2026-05-19 20:15:30 +02:00
parent 269789b36f
commit 591693da1d
11 changed files with 159 additions and 62 deletions

View file

@ -13,21 +13,21 @@ namespace Module.ProjectValidator.Editor
private readonly Dictionary<GUID, MappingEntry> _assetToSeverityMapping = new(); private readonly Dictionary<GUID, MappingEntry> _assetToSeverityMapping = new();
private readonly Dictionary<int, MappingEntry> _instanceToSeverityMapping = new(); private readonly Dictionary<int, MappingEntry> _instanceToSeverityMapping = new();
public void Add(GUID assetGuid, string scenePath, string fieldPath, Attribute attribute, EValidatorSeverity severity, string message) public void Add(GUID assetGuid, string relativePath, string fieldPath, Attribute attribute, EValidatorSeverity severity, string message)
{ {
var type = ProjectValidatorUtility.GetAttributeShortName(attribute); var type = ProjectValidatorUtility.GetAttributeShortName(attribute);
Add(assetGuid, scenePath, fieldPath, type, severity, message); Add(assetGuid, relativePath, fieldPath, type, severity, message);
} }
public void Add(GUID assetGuid, string scenePath, string fieldPath, string type, EValidatorSeverity severity, string message) public void Add(GUID assetGuid, string relativePath, string fieldPath, string type, EValidatorSeverity severity, string message)
{ {
Entries.Add(new Entry Entries.Add(new Entry
{ {
AssetGuid = assetGuid, AssetGuid = assetGuid,
AssetName = EditorAssetUtility.GetAssetName(assetGuid), AssetName = EditorAssetUtility.GetAssetName(assetGuid),
ScenePath = scenePath, RelativePath = relativePath,
FieldPath = fieldPath, FieldPath = fieldPath,
ScenePathRichText = ProjectValidatorUtility.ApplyRichTextToScenePath(scenePath), RelativePathRichText = ProjectValidatorUtility.ApplyRichTextToRelativePath(relativePath),
FieldPathRichText = ProjectValidatorUtility.ApplyRichTextToFieldPath(fieldPath), FieldPathRichText = ProjectValidatorUtility.ApplyRichTextToFieldPath(fieldPath),
Type = type, Type = type,
Severity = severity, Severity = severity,
@ -74,7 +74,7 @@ namespace Module.ProjectValidator.Editor
return false; return false;
} }
public bool TryGetSeverityFor(GUID assetGuid, string scenePath, out MappingEntry mapping) public bool TryGetSeverityFor(GUID assetGuid, string relativePath, out MappingEntry mapping)
{ {
if (!_assetToSeverityMapping.TryGetValue(assetGuid, out mapping)) if (!_assetToSeverityMapping.TryGetValue(assetGuid, out mapping))
return false; return false;
@ -83,7 +83,7 @@ namespace Module.ProjectValidator.Editor
for (var i = 0; i < Entries.Count; i++) for (var i = 0; i < Entries.Count; i++)
{ {
if (Entries[i].AssetGuid != assetGuid || Entries[i].ScenePath != scenePath || Entries[i].Severity <= mapping.Severity) if (Entries[i].AssetGuid != assetGuid || Entries[i].RelativePath != relativePath || Entries[i].Severity <= mapping.Severity)
continue; continue;
mapping = new MappingEntry(Entries[i].Severity, false); mapping = new MappingEntry(Entries[i].Severity, false);
@ -110,10 +110,10 @@ namespace Module.ProjectValidator.Editor
public GUID AssetGuid; public GUID AssetGuid;
public string AssetName; public string AssetName;
public string ScenePath; public string RelativePath;
public string FieldPath; public string FieldPath;
public string ScenePathRichText; public string RelativePathRichText;
public string FieldPathRichText; public string FieldPathRichText;
public string Type; public string Type;
@ -124,7 +124,7 @@ namespace Module.ProjectValidator.Editor
public bool Filter(string filter) public bool Filter(string filter)
{ {
return AssetName.Contains(filter, StringComparison.InvariantCultureIgnoreCase) || return AssetName.Contains(filter, StringComparison.InvariantCultureIgnoreCase) ||
ScenePath.Contains(filter, StringComparison.InvariantCultureIgnoreCase) || RelativePath.Contains(filter, StringComparison.InvariantCultureIgnoreCase) ||
FieldPath.Contains(filter, StringComparison.InvariantCultureIgnoreCase) || FieldPath.Contains(filter, StringComparison.InvariantCultureIgnoreCase) ||
Type.Contains(filter, StringComparison.InvariantCultureIgnoreCase) || Type.Contains(filter, StringComparison.InvariantCultureIgnoreCase) ||
SeverityResult.Contains(filter, StringComparison.InvariantCultureIgnoreCase) || SeverityResult.Contains(filter, StringComparison.InvariantCultureIgnoreCase) ||

View file

@ -31,20 +31,21 @@ namespace Module.ProjectValidator.Editor
internal static GUID GetAssetGuid(Object obj) internal static GUID GetAssetGuid(Object obj)
{ {
var assetGuid = new GUID(); var assetPath = string.Empty;
if (obj is GameObject gameObject) if (obj is GameObject gameObject)
{ {
if (gameObject.scene.isLoaded) if (gameObject.scene.isLoaded)
GUID.TryParse(AssetDatabase.AssetPathToGUID(gameObject.scene.path), out assetGuid); assetPath = gameObject.scene.path;
else if (PrefabUtility.IsPartOfPrefabAsset(gameObject)) else if (PrefabUtility.IsPartOfPrefabAsset(gameObject))
GUID.TryParse(AssetDatabase.AssetPathToGUID(gameObject.scene.path), out assetGuid); assetPath = AssetDatabase.GetAssetPath(gameObject);
} }
else else
{ {
GUID.TryParse(AssetDatabase.GetAssetPath(obj), out assetGuid); assetPath = AssetDatabase.GetAssetPath(obj);
} }
GUID.TryParse(AssetDatabase.AssetPathToGUID(assetPath), out var assetGuid);
return assetGuid; return assetGuid;
} }

View file

@ -62,14 +62,17 @@ namespace Module.ProjectValidator.Editor
return str; return str;
} }
internal static void AppendToScenePath(GameObject gameObject, ref string scenePath) internal static void AppendToRelativePath(GameObject gameObject, ref string relativePath, bool initial)
{ {
scenePath = string.IsNullOrEmpty(scenePath) ? gameObject.name : $"{scenePath}/{gameObject.name}"; if (string.IsNullOrEmpty(relativePath))
relativePath = gameObject.name;
else
relativePath = initial ? $"{relativePath}{gameObject.name}" : $"{relativePath}/{gameObject.name}";
} }
internal static string ApplyRichTextToScenePath(string scenePath) internal static string ApplyRichTextToRelativePath(string relativePath)
{ {
return scenePath.Replace("/", "<color=#00ff00><b>/</b></color>"); return relativePath.Replace("/", "<color=#00ff00><b>/</b></color>");
} }
public static void AppendToFieldPath(FieldInfo fieldInfo, ref string fieldPath) public static void AppendToFieldPath(FieldInfo fieldInfo, ref string fieldPath)
@ -105,7 +108,7 @@ namespace Module.ProjectValidator.Editor
{ {
var scene = SceneManager.GetSceneByPath(assetPath); var scene = SceneManager.GetSceneByPath(assetPath);
if (scene.isLoaded && TryFindSceneObjectByPath(scene, entry.ScenePath, out var gameObject)) if (scene.isLoaded && TryFindSceneObjectByPath(scene, entry.RelativePath, out var gameObject))
EditorGUIUtility.PingObject(gameObject); EditorGUIUtility.PingObject(gameObject);
else else
EditorGUIUtility.PingObject(asset); EditorGUIUtility.PingObject(asset);
@ -116,14 +119,14 @@ namespace Module.ProjectValidator.Editor
} }
} }
private static bool TryFindSceneObjectByPath(Scene scene, string scenePath, out GameObject gameObject) private static bool TryFindSceneObjectByPath(Scene scene, string relativePath, out GameObject gameObject)
{ {
using var _ = ListPool<GameObject>.Get(out var rootObjects); using var _ = ListPool<GameObject>.Get(out var rootObjects);
scene.GetRootGameObjects(rootObjects); scene.GetRootGameObjects(rootObjects);
var index = scenePath.IndexOf('/'); var index = relativePath.IndexOf('/');
var rootName = index != -1 ? scenePath[..index] : scenePath; var rootName = index != -1 ? relativePath[..index] : relativePath;
var childPath = index != -1 ? scenePath[(index + 1)..] : string.Empty; var childPath = index != -1 ? relativePath[(index + 1)..] : string.Empty;
for (var i = 0; i < rootObjects.Count; i++) for (var i = 0; i < rootObjects.Count; i++)
{ {
@ -212,25 +215,25 @@ namespace Module.ProjectValidator.Editor
for (var j = 0; j < rootObjects.Count; j++) for (var j = 0; j < rootObjects.Count; j++)
{ {
var rootObject = rootObjects[j]; var rootObject = rootObjects[j];
var scenePath = string.Empty; var relativePath = string.Empty;
RebuildSceneInstanceMapping(report, dictMapping, rootObject, assetGuid, scenePath); RebuildSceneInstanceMapping(report, dictMapping, rootObject, assetGuid, relativePath, true);
} }
} }
RebuildForAllParents(dictMapping); RebuildForAllParents(dictMapping);
} }
private static void RebuildSceneInstanceMapping(Report report, Dictionary<int, Report.MappingEntry> dictMapping, GameObject gameObject, GUID assetGuid, string scenePath) private static void RebuildSceneInstanceMapping(Report report, Dictionary<int, Report.MappingEntry> dictMapping, GameObject gameObject, GUID assetGuid, string relativePath, bool initial)
{ {
var transform = gameObject.transform; var transform = gameObject.transform;
AppendToScenePath(gameObject, ref scenePath); AppendToRelativePath(gameObject, ref relativePath, initial);
if (report.TryGetSeverityFor(assetGuid, scenePath, out var mapping)) if (report.TryGetSeverityFor(assetGuid, relativePath, out var mapping))
dictMapping.Add(gameObject.GetInstanceID(), new Report.MappingEntry(mapping.Severity, false)); dictMapping.Add(gameObject.GetInstanceID(), new Report.MappingEntry(mapping.Severity, false));
for (var i = 0; i < transform.childCount; i++) for (var i = 0; i < transform.childCount; i++)
{ {
RebuildSceneInstanceMapping(report, dictMapping, transform.GetChild(i).gameObject, assetGuid, scenePath); RebuildSceneInstanceMapping(report, dictMapping, transform.GetChild(i).gameObject, assetGuid, relativePath, false);
} }
} }

View file

@ -30,6 +30,7 @@ namespace Module.ProjectValidator.Editor
var report = new Report(); var report = new Report();
ValidateAllScenes(report); ValidateAllScenes(report);
ValidateAllAssets(report); ValidateAllAssets(report);
ValidateAllPrefabs(report);
report.RebuildAssetMapping(); report.RebuildAssetMapping();
report.RebuildInstanceMapping(); report.RebuildInstanceMapping();
report.SetAsActive(); report.SetAsActive();
@ -155,7 +156,7 @@ namespace Module.ProjectValidator.Editor
for (var j = 0; j < rootObjects.Count; j++) for (var j = 0; j < rootObjects.Count; j++)
{ {
ValidateGameObject(rootObjects[j], string.Empty, report); ValidateGameObject(rootObjects[j], "scene:", report, true);
} }
if (!isLoaded) if (!isLoaded)
@ -173,6 +174,23 @@ namespace Module.ProjectValidator.Editor
ValidateAssetsBytype<ScriptableObject>(report); ValidateAssetsBytype<ScriptableObject>(report);
} }
private static void ValidateAllPrefabs(Report report)
{
var assets = EditorAssetUtility.LoadAllAssets<GameObject>();
for (var i = 0; i < assets.Length; i++)
{
try
{
ValidateGameObject(assets[i], "prefab:", report, true);
}
catch (Exception e)
{
Debug.LogException(e);
}
}
}
private static void ValidateAssetsBytype<T>(Report report) where T : UnityEngine.Object private static void ValidateAssetsBytype<T>(Report report) where T : UnityEngine.Object
{ {
var assets = EditorAssetUtility.LoadAllAssets<T>(); var assets = EditorAssetUtility.LoadAllAssets<T>();
@ -193,12 +211,13 @@ namespace Module.ProjectValidator.Editor
private static void ValidateUnityObject(UnityEngine.Object obj, Report report) private static void ValidateUnityObject(UnityEngine.Object obj, Report report)
{ {
var assetGuid = EditorAssetUtility.ObjectToAssetGuid(obj); var assetGuid = EditorAssetUtility.ObjectToAssetGuid(obj);
Validate(assetGuid, string.Empty, obj, report); var assetPath = AssetDatabase.GUIDToAssetPath(assetGuid);
Validate(assetGuid, $"asset:{assetPath}", obj, report);
} }
private static void ValidateGameObject(GameObject gameObject, string scenePath, Report report) private static void ValidateGameObject(GameObject gameObject, string relativePath, Report report, bool initial)
{ {
ProjectValidatorUtility.AppendToScenePath(gameObject, ref scenePath); ProjectValidatorUtility.AppendToRelativePath(gameObject, ref relativePath, initial);
var assetGuid = EditorAssetUtility.GetAssetGuid(gameObject); var assetGuid = EditorAssetUtility.GetAssetGuid(gameObject);
using var _ = ListPool<ValidatorResult>.Get(out var results); using var _ = ListPool<ValidatorResult>.Get(out var results);
@ -215,15 +234,15 @@ namespace Module.ProjectValidator.Editor
var result = results[j]; var result = results[j];
if (result.Severity != EValidatorSeverity.Valid) if (result.Severity != EValidatorSeverity.Valid)
report.Add(assetGuid, scenePath, string.Empty, type, result.Severity, result.Message); report.Add(assetGuid, relativePath, string.Empty, type, result.Severity, result.Message);
} }
} }
ValidateComponents(gameObject, assetGuid, scenePath, report); ValidateComponents(gameObject, assetGuid, relativePath, report);
ValidateChildren(gameObject, scenePath, report); ValidateChildren(gameObject, relativePath, report);
} }
private static void ValidateComponents(GameObject gameObject, GUID assetGuid, string scenePath, Report report) private static void ValidateComponents(GameObject gameObject, GUID assetGuid, string relativePath, Report report)
{ {
using var _ = ListPool<Component>.Get(out var components); using var _ = ListPool<Component>.Get(out var components);
gameObject.GetComponents(components); gameObject.GetComponents(components);
@ -231,21 +250,21 @@ namespace Module.ProjectValidator.Editor
for (var i = 0; i < components.Count; i++) for (var i = 0; i < components.Count; i++)
{ {
if (components[i] != null) if (components[i] != null)
Validate(assetGuid, scenePath, components[i], report); Validate(assetGuid, relativePath, components[i], report);
} }
} }
private static void ValidateChildren(GameObject gameObject, string scenePath, Report report) private static void ValidateChildren(GameObject gameObject, string relativePath, Report report)
{ {
var transform = gameObject.transform; var transform = gameObject.transform;
for (var i = 0; i < transform.childCount; i++) for (var i = 0; i < transform.childCount; i++)
{ {
ValidateGameObject(transform.GetChild(i).gameObject, scenePath, report); ValidateGameObject(transform.GetChild(i).gameObject, relativePath, report, false);
} }
} }
private static void Validate(GUID assetGuid, string scenePath, object obj, Report report) private static void Validate(GUID assetGuid, string relativePath, object obj, Report report)
{ {
var type = obj.GetType(); var type = obj.GetType();
@ -253,10 +272,10 @@ namespace Module.ProjectValidator.Editor
return; return;
var fieldPath = obj.GetType().Name; var fieldPath = obj.GetType().Name;
Validate(assetGuid, scenePath, fieldPath, obj, entry, report); Validate(assetGuid, relativePath, fieldPath, obj, entry, report);
} }
private static void Validate(GUID assetGuid, string scenePath, string parentFieldPath, object obj, TypeTree.Entry entry, Report report) private static void Validate(GUID assetGuid, string relativePath, string parentFieldPath, object obj, TypeTree.Entry entry, Report report)
{ {
if (obj == null) if (obj == null)
return; return;
@ -268,7 +287,7 @@ namespace Module.ProjectValidator.Editor
try try
{ {
var component = entry.Components[i]; var component = entry.Components[i];
ValidateComponent(component, obj, assetGuid, scenePath, report); ValidateComponent(component, obj, assetGuid, relativePath, report);
} }
catch (Exception e) catch (Exception e)
{ {
@ -297,13 +316,13 @@ namespace Module.ProjectValidator.Editor
{ {
var fieldPathArrElement = fieldPath; var fieldPathArrElement = fieldPath;
ProjectValidatorUtility.AppendToFieldPath(idx, ref fieldPathArrElement); ProjectValidatorUtility.AppendToFieldPath(idx, ref fieldPathArrElement);
ValidateField(field, eObj, assetGuid, scenePath, fieldPathArrElement, report); ValidateField(field, eObj, assetGuid, relativePath, fieldPathArrElement, report);
idx++; idx++;
} }
} }
else else
{ {
ValidateField(field, value, assetGuid, scenePath, fieldPath, report); ValidateField(field, value, assetGuid, relativePath, fieldPath, report);
} }
} }
catch (Exception e) catch (Exception e)
@ -333,13 +352,13 @@ namespace Module.ProjectValidator.Editor
{ {
var fieldPathArrElement = fieldPath; var fieldPathArrElement = fieldPath;
ProjectValidatorUtility.AppendToFieldPath(idx, ref fieldPathArrElement); ProjectValidatorUtility.AppendToFieldPath(idx, ref fieldPathArrElement);
Validate(assetGuid, scenePath, fieldPathArrElement, eObj, e.Entry, report); Validate(assetGuid, relativePath, fieldPathArrElement, eObj, e.Entry, report);
idx++; idx++;
} }
} }
else else
{ {
Validate(assetGuid, scenePath, fieldPath, value, e.Entry, report); Validate(assetGuid, relativePath, fieldPath, value, e.Entry, report);
} }
} }
catch (Exception e) catch (Exception e)
@ -350,15 +369,15 @@ namespace Module.ProjectValidator.Editor
} }
} }
private static void ValidateField(TypeTree.ValidatorField field, object value, GUID assetGuid, string scenePath, string fieldPath, Report report) private static void ValidateField(TypeTree.ValidatorField field, object value, GUID assetGuid, string relativePath, string fieldPath, Report report)
{ {
var result = (ValidatorResult)field.ValidatorMethod.Invoke(field.Validator, new[] { field.Attribute, value }); var result = (ValidatorResult)field.ValidatorMethod.Invoke(field.Validator, new[] { field.Attribute, value });
if (result.Severity != EValidatorSeverity.Valid) if (result.Severity != EValidatorSeverity.Valid)
report.Add(assetGuid, scenePath, fieldPath, field.Attribute, result.Severity, result.Message); report.Add(assetGuid, relativePath, fieldPath, field.Attribute, result.Severity, result.Message);
} }
private static void ValidateComponent(TypeTree.ValidatorComponent component, object value, GUID assetGuid, string scenePath, Report report) private static void ValidateComponent(TypeTree.ValidatorComponent component, object value, GUID assetGuid, string relativePath, Report report)
{ {
using var _ = ListPool<ValidatorResult>.Get(out var results); using var _ = ListPool<ValidatorResult>.Get(out var results);
component.ValidatorMethod.Invoke(component.Validator, new[] { value, results }); component.ValidatorMethod.Invoke(component.Validator, new[] { value, results });
@ -369,7 +388,7 @@ namespace Module.ProjectValidator.Editor
var result = results[i]; var result = results[i];
if (result.Severity != EValidatorSeverity.Valid) if (result.Severity != EValidatorSeverity.Valid)
report.Add(assetGuid, scenePath, string.Empty, type, result.Severity, result.Message); report.Add(assetGuid, relativePath, string.Empty, type, result.Severity, result.Message);
} }
} }
} }

View file

@ -0,0 +1,43 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
namespace Module.ProjectValidator.Editor
{
internal sealed class GameObjectValidatorDuplicateComponents : IGameObjectValidator
{
public void Validate(GameObject gameObject, List<ValidatorResult> results)
{
using var _ = ListPool<Component>.Get(out var list);
gameObject.GetComponents(list);
list.Sort((c0, c1) => c0.GetType().GetHashCode().CompareTo(c1.GetType().GetHashCode()));
if (list.Count == 0)
return;
var type = list[0].GetType();
var count = 1;
for (var i = 1; i < list.Count; i++)
{
var t = list[i].GetType();
if (type == t)
{
count++;
}
else
{
if (count > 1)
results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"GameObject has duplicate '{type.Name}' ({count}) components"));
type = t;
count = 1;
}
}
if (count > 1)
results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"GameObject has duplicate '{type.Name}' ({count}) components"));
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b27a4e96523d4d3d97c11b32814f29d3
timeCreated: 1779213834

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Pool;
namespace Module.ProjectValidator.Editor
{
internal sealed class GameObjectValidatorObsoleteComponents : IGameObjectValidator
{
public void Validate(GameObject gameObject, List<ValidatorResult> results)
{
using var _ = ListPool<Component>.Get(out var list);
gameObject.GetComponents(list);
for (var i = 0; i < list.Count; i++)
{
var type = list[i].GetType();
if (type.GetCustomAttribute(typeof(ObsoleteAttribute)) != null)
results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"GameObject has obsolete '{type.Name}' component"));
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ca678bbf72fa4c8f8c9b945535aacf44
timeCreated: 1779214145

View file

@ -30,14 +30,14 @@ namespace Module.ProjectValidator.Editor
_treeView.columns["type"].makeCell = CreateLabel; _treeView.columns["type"].makeCell = CreateLabel;
_treeView.columns["severity"].makeCell = CreateLabel; _treeView.columns["severity"].makeCell = CreateLabel;
_treeView.columns["severity-message"].makeCell = CreateLabel; _treeView.columns["severity-message"].makeCell = CreateLabel;
_treeView.columns["scene-path"].makeCell = CreateLabel; _treeView.columns["relative-path"].makeCell = CreateLabel;
_treeView.columns["field-path"].makeCell = CreateLabel; _treeView.columns["field-path"].makeCell = CreateLabel;
_treeView.columns["asset"].bindCell = OnTreeViewBindCellAsset; _treeView.columns["asset"].bindCell = OnTreeViewBindCellAsset;
_treeView.columns["type"].bindCell = OnTreeViewBindCellType; _treeView.columns["type"].bindCell = OnTreeViewBindCellType;
_treeView.columns["severity"].bindCell = OnTreeViewBindCellSeverity; _treeView.columns["severity"].bindCell = OnTreeViewBindCellSeverity;
_treeView.columns["severity-message"].bindCell = OnTreeViewBindCellSeverityMessage; _treeView.columns["severity-message"].bindCell = OnTreeViewBindCellSeverityMessage;
_treeView.columns["scene-path"].bindCell = OnTreeViewBindCellScenePath; _treeView.columns["relative-path"].bindCell = OnTreeViewBindCellRelativePath;
_treeView.columns["field-path"].bindCell = OnTreeViewBindCellFieldPath; _treeView.columns["field-path"].bindCell = OnTreeViewBindCellFieldPath;
_treeView.columns["severity"].unbindCell = OnTreeViewUnbindCellSeverity; _treeView.columns["severity"].unbindCell = OnTreeViewUnbindCellSeverity;
@ -46,7 +46,7 @@ namespace Module.ProjectValidator.Editor
_treeView.columns["type"].comparison = OnTreeViewComparisonCellType; _treeView.columns["type"].comparison = OnTreeViewComparisonCellType;
_treeView.columns["severity"].comparison = OnTreeViewComparisonCellSeverity; _treeView.columns["severity"].comparison = OnTreeViewComparisonCellSeverity;
_treeView.columns["severity-message"].comparison = OnTreeViewComparisonCellSeverityMessage; _treeView.columns["severity-message"].comparison = OnTreeViewComparisonCellSeverityMessage;
_treeView.columns["scene-path"].comparison = OnTreeViewComparisonCellScenePath; _treeView.columns["relative-path"].comparison = OnTreeViewComparisonCellRelativePath;
_treeView.columns["field-path"].comparison = OnTreeViewComparisonCellFieldPath; _treeView.columns["field-path"].comparison = OnTreeViewComparisonCellFieldPath;
_treeView.selectionChanged += OnTreeViewSelectionChanged; _treeView.selectionChanged += OnTreeViewSelectionChanged;
@ -170,11 +170,11 @@ namespace Module.ProjectValidator.Editor
label.text = entry.SeverityResult; label.text = entry.SeverityResult;
} }
private void OnTreeViewBindCellScenePath(VisualElement ve, int index) private void OnTreeViewBindCellRelativePath(VisualElement ve, int index)
{ {
var label = (Label)ve; var label = (Label)ve;
var entry = _treeView.GetItemDataForIndex<Report.Entry>(index); var entry = _treeView.GetItemDataForIndex<Report.Entry>(index);
label.text = entry.ScenePathRichText; label.text = entry.RelativePathRichText;
} }
private void OnTreeViewBindCellFieldPath(VisualElement ve, int index) private void OnTreeViewBindCellFieldPath(VisualElement ve, int index)
@ -222,11 +222,11 @@ namespace Module.ProjectValidator.Editor
return string.Compare(entry0.SeverityResult, entry1.SeverityResult, StringComparison.Ordinal); return string.Compare(entry0.SeverityResult, entry1.SeverityResult, StringComparison.Ordinal);
} }
private int OnTreeViewComparisonCellScenePath(int index0, int index1) private int OnTreeViewComparisonCellRelativePath(int index0, int index1)
{ {
var entry0 = _treeView.GetItemDataForIndex<Report.Entry>(index0); var entry0 = _treeView.GetItemDataForIndex<Report.Entry>(index0);
var entry1 = _treeView.GetItemDataForIndex<Report.Entry>(index1); var entry1 = _treeView.GetItemDataForIndex<Report.Entry>(index1);
return string.Compare(entry0.ScenePath, entry1.ScenePath, StringComparison.Ordinal); return string.Compare(entry0.RelativePath, entry1.RelativePath, StringComparison.Ordinal);
} }
private int OnTreeViewComparisonCellFieldPath(int index0, int index1) private int OnTreeViewComparisonCellFieldPath(int index0, int index1)

View file

@ -10,7 +10,7 @@
<ui:Column name="severity" title="Severity" min-width="80px" optional="true"/> <ui:Column name="severity" title="Severity" min-width="80px" optional="true"/>
<ui:Column name="type" title="Type" min-width="42px" width="120px"/> <ui:Column name="type" title="Type" min-width="42px" width="120px"/>
<ui:Column name="asset" title="Asset" optional="true" min-width="80px" width="200px"/> <ui:Column name="asset" title="Asset" optional="true" min-width="80px" width="200px"/>
<ui:Column optional="true" name="scene-path" title="Scene Path" min-width="40px" width="200px"/> <ui:Column optional="true" name="relative-path" title="Path" min-width="40px" width="200px"/>
<ui:Column name="field-path" title="Field Path" min-width="70px" width="200px"/> <ui:Column name="field-path" title="Field Path" min-width="70px" width="200px"/>
<ui:Column optional="true" name="severity-message" title="Message" stretchable="true"/> <ui:Column optional="true" name="severity-message" title="Message" stretchable="true"/>
</ui:Columns> </ui:Columns>

View file

@ -1,6 +1,6 @@
{ {
"name": "com.module.project-validator", "name": "com.module.project-validator",
"version": "0.3.0", "version": "0.4.0",
"displayName": "Module.ProjectValidator", "displayName": "Module.ProjectValidator",
"description": "", "description": "",
"unity": "6000.3", "unity": "6000.3",