mirror of
https://github.com/maxartz15/Validator.git
synced 2025-07-04 06:26:04 +02:00
Compare commits
7 Commits
1.1.0
...
5b70e24c32
Author | SHA1 | Date | |
---|---|---|---|
5b70e24c32 | |||
15808ce035 | |||
8399d043f5 | |||
b4dd8744df | |||
b13cf47fbf | |||
9c01bed215 | |||
74fd067220 |
@ -1,4 +1,12 @@
|
|||||||
# Change Log:
|
# Change Log:
|
||||||
|
## 0.1.4
|
||||||
|
- Fix attribute validator..?
|
||||||
|
## 0.1.3
|
||||||
|
- Fix attribute validator..?
|
||||||
|
## 0.1.2
|
||||||
|
- ...
|
||||||
|
## 0.1.1
|
||||||
|
- First prototype of Attribute validator.
|
||||||
## 0.1.1
|
## 0.1.1
|
||||||
- Search input.
|
- Search input.
|
||||||
- GUI toolbar.
|
- GUI toolbar.
|
||||||
|
BIN
Documentation~/Images/ValidatorWindow_01.png
Normal file
BIN
Documentation~/Images/ValidatorWindow_01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
@ -1,7 +1,8 @@
|
|||||||
namespace Validator.Editor
|
namespace Validator.Editor
|
||||||
{
|
{
|
||||||
public interface IValidator
|
public interface IValidator
|
||||||
{
|
{
|
||||||
public Report Validate();
|
public string MenuName { get; }
|
||||||
}
|
public Report Validate();
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,432 +8,432 @@ using Object = UnityEngine.Object;
|
|||||||
|
|
||||||
namespace Validator.Editor
|
namespace Validator.Editor
|
||||||
{
|
{
|
||||||
public class ValidatorEditorWindow : EditorWindow
|
public class ValidatorEditorWindow : EditorWindow
|
||||||
{
|
{
|
||||||
private class ValidatorInfo
|
private class ValidatorInfo
|
||||||
{
|
{
|
||||||
public IValidator validator = null;
|
public IValidator validator = null;
|
||||||
public bool isEnabled = true;
|
public bool isEnabled = true;
|
||||||
|
|
||||||
public ValidatorInfo(IValidator validator)
|
public ValidatorInfo(IValidator validator)
|
||||||
{
|
{
|
||||||
this.validator = validator;
|
this.validator = validator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReportStats
|
private class ReportStats
|
||||||
{
|
{
|
||||||
public int infoCount = 0;
|
public int infoCount = 0;
|
||||||
public int warningCount = 0;
|
public int warningCount = 0;
|
||||||
public int errorCount = 0;
|
public int errorCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Settings
|
private class Settings
|
||||||
{
|
{
|
||||||
public bool showInfo = true;
|
public bool showInfo = true;
|
||||||
public bool showWarning = true;
|
public bool showWarning = true;
|
||||||
public bool showError = true;
|
public bool showError = true;
|
||||||
public string searchInput = "";
|
public string searchInput = "";
|
||||||
|
|
||||||
public readonly Color lightColor = new Color(0.25f, 0.25f, 0.25f, 1);
|
public readonly Color lightColor = new Color(0.25f, 0.25f, 0.25f, 1);
|
||||||
public readonly Color darkColor = new Color(0.22f, 0.22f, 0.22f, 1);
|
public readonly Color darkColor = new Color(0.22f, 0.22f, 0.22f, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly List<ValidatorInfo> validators = new List<ValidatorInfo>();
|
private static readonly List<ValidatorInfo> validators = new List<ValidatorInfo>();
|
||||||
private static readonly List<Report> reports = new List<Report>();
|
private static readonly List<Report> reports = new List<Report>();
|
||||||
|
|
||||||
private static readonly Settings settings = new Settings();
|
private static readonly Settings settings = new Settings();
|
||||||
private static ReportStats reportStats = new ReportStats();
|
private static ReportStats reportStats = new ReportStats();
|
||||||
|
|
||||||
private MultiColumnHeaderState multiColumnHeaderState;
|
private MultiColumnHeaderState multiColumnHeaderState;
|
||||||
private MultiColumnHeader multiColumnHeader;
|
private MultiColumnHeader multiColumnHeader;
|
||||||
private MultiColumnHeaderState.Column[] columns;
|
private MultiColumnHeaderState.Column[] columns;
|
||||||
private Vector2 scrollPosition;
|
private Vector2 scrollPosition;
|
||||||
private float multiColumnHeaderWidth;
|
private float multiColumnHeaderWidth;
|
||||||
private float rows;
|
private float rows;
|
||||||
|
|
||||||
[MenuItem("Window/General/Validator")]
|
[MenuItem("Window/General/Validator")]
|
||||||
private static void Init()
|
private static void Init()
|
||||||
{
|
{
|
||||||
ValidatorEditorWindow window = (ValidatorEditorWindow)GetWindow(typeof(ValidatorEditorWindow));
|
ValidatorEditorWindow window = (ValidatorEditorWindow)GetWindow(typeof(ValidatorEditorWindow));
|
||||||
window.titleContent = new GUIContent("Validator", EditorGUIUtility.IconContent("d_UnityEditor.ConsoleWindow").image);
|
window.titleContent = new GUIContent("Validator", EditorGUIUtility.IconContent("d_UnityEditor.ConsoleWindow").image);
|
||||||
window.Show();
|
window.Show();
|
||||||
window.LoadValidators();
|
window.LoadValidators();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
{
|
|
||||||
using (new EditorGUILayout.VerticalScope(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)))
|
|
||||||
{
|
|
||||||
DrawMenu();
|
|
||||||
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
|
|
||||||
DrawMultiColumnScope();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeMultiColumn()
|
|
||||||
{
|
{
|
||||||
columns = new MultiColumnHeaderState.Column[]
|
using (new EditorGUILayout.VerticalScope(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)))
|
||||||
{
|
{
|
||||||
new MultiColumnHeaderState.Column()
|
DrawMenu();
|
||||||
{
|
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
|
||||||
allowToggleVisibility = false, // At least one column must be there.
|
DrawMultiColumnScope();
|
||||||
autoResize = false,
|
}
|
||||||
width = 36f,
|
}
|
||||||
minWidth = 36f,
|
|
||||||
maxWidth = 36f,
|
|
||||||
canSort = false,
|
|
||||||
sortingArrowAlignment = TextAlignment.Right,
|
|
||||||
headerContent = EditorGUIUtility.IconContent("d_console.erroricon.inactive.sml", "Warning Type."),
|
|
||||||
headerTextAlignment = TextAlignment.Center,
|
|
||||||
},
|
|
||||||
new MultiColumnHeaderState.Column()
|
|
||||||
{
|
|
||||||
allowToggleVisibility = true,
|
|
||||||
autoResize = false,
|
|
||||||
width = 36f,
|
|
||||||
minWidth = 36f,
|
|
||||||
maxWidth = 36f,
|
|
||||||
canSort = false,
|
|
||||||
sortingArrowAlignment = TextAlignment.Right,
|
|
||||||
headerContent = EditorGUIUtility.IconContent("Animation.FilterBySelection", "Target Objects"),
|
|
||||||
headerTextAlignment = TextAlignment.Center,
|
|
||||||
},
|
|
||||||
new MultiColumnHeaderState.Column()
|
|
||||||
{
|
|
||||||
allowToggleVisibility = true,
|
|
||||||
autoResize = true,
|
|
||||||
width = 75.0f,
|
|
||||||
minWidth = 75.0f,
|
|
||||||
canSort = false,
|
|
||||||
sortingArrowAlignment = TextAlignment.Right,
|
|
||||||
headerContent = new GUIContent("Category", "Warning Category."),
|
|
||||||
headerTextAlignment = TextAlignment.Center,
|
|
||||||
},
|
|
||||||
new MultiColumnHeaderState.Column()
|
|
||||||
{
|
|
||||||
allowToggleVisibility = true,
|
|
||||||
autoResize = true,
|
|
||||||
width = 200.0f,
|
|
||||||
minWidth = 200.0f,
|
|
||||||
canSort = false,
|
|
||||||
sortingArrowAlignment = TextAlignment.Right,
|
|
||||||
headerContent = new GUIContent("Message", "Warning Message."),
|
|
||||||
headerTextAlignment = TextAlignment.Center,
|
|
||||||
},
|
|
||||||
new MultiColumnHeaderState.Column()
|
|
||||||
{
|
|
||||||
allowToggleVisibility = true,
|
|
||||||
autoResize = true,
|
|
||||||
width = 200.0f,
|
|
||||||
minWidth = 200.0f,
|
|
||||||
canSort = false,
|
|
||||||
sortingArrowAlignment = TextAlignment.Right,
|
|
||||||
headerContent = new GUIContent("Solution", "Warning Solution."),
|
|
||||||
headerTextAlignment = TextAlignment.Center,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
multiColumnHeaderState = new MultiColumnHeaderState(columns);
|
private void InitializeMultiColumn()
|
||||||
multiColumnHeader = new MultiColumnHeader(multiColumnHeaderState);
|
|
||||||
multiColumnHeader.ResizeToFit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawMenu()
|
|
||||||
{
|
{
|
||||||
using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar))
|
columns = new MultiColumnHeaderState.Column[]
|
||||||
{
|
{
|
||||||
if (GUILayout.Button(EditorGUIUtility.IconContent("Refresh", "Refresh"), EditorStyles.toolbarButton))
|
new MultiColumnHeaderState.Column()
|
||||||
{
|
{
|
||||||
LoadValidators();
|
allowToggleVisibility = false, // At least one column must be there.
|
||||||
}
|
autoResize = false,
|
||||||
|
width = 36f,
|
||||||
|
minWidth = 36f,
|
||||||
|
maxWidth = 36f,
|
||||||
|
canSort = false,
|
||||||
|
sortingArrowAlignment = TextAlignment.Right,
|
||||||
|
headerContent = EditorGUIUtility.IconContent("d_console.erroricon.inactive.sml", "Warning Type."),
|
||||||
|
headerTextAlignment = TextAlignment.Center,
|
||||||
|
},
|
||||||
|
new MultiColumnHeaderState.Column()
|
||||||
|
{
|
||||||
|
allowToggleVisibility = true,
|
||||||
|
autoResize = false,
|
||||||
|
width = 36f,
|
||||||
|
minWidth = 36f,
|
||||||
|
maxWidth = 36f,
|
||||||
|
canSort = false,
|
||||||
|
sortingArrowAlignment = TextAlignment.Right,
|
||||||
|
headerContent = EditorGUIUtility.IconContent("Animation.FilterBySelection", "Target Objects"),
|
||||||
|
headerTextAlignment = TextAlignment.Center,
|
||||||
|
},
|
||||||
|
new MultiColumnHeaderState.Column()
|
||||||
|
{
|
||||||
|
allowToggleVisibility = true,
|
||||||
|
autoResize = true,
|
||||||
|
width = 75.0f,
|
||||||
|
minWidth = 75.0f,
|
||||||
|
canSort = false,
|
||||||
|
sortingArrowAlignment = TextAlignment.Right,
|
||||||
|
headerContent = new GUIContent("Category", "Warning Category."),
|
||||||
|
headerTextAlignment = TextAlignment.Center,
|
||||||
|
},
|
||||||
|
new MultiColumnHeaderState.Column()
|
||||||
|
{
|
||||||
|
allowToggleVisibility = true,
|
||||||
|
autoResize = true,
|
||||||
|
width = 200.0f,
|
||||||
|
minWidth = 200.0f,
|
||||||
|
canSort = false,
|
||||||
|
sortingArrowAlignment = TextAlignment.Right,
|
||||||
|
headerContent = new GUIContent("Message", "Warning Message."),
|
||||||
|
headerTextAlignment = TextAlignment.Center,
|
||||||
|
},
|
||||||
|
new MultiColumnHeaderState.Column()
|
||||||
|
{
|
||||||
|
allowToggleVisibility = true,
|
||||||
|
autoResize = true,
|
||||||
|
width = 200.0f,
|
||||||
|
minWidth = 200.0f,
|
||||||
|
canSort = false,
|
||||||
|
sortingArrowAlignment = TextAlignment.Right,
|
||||||
|
headerContent = new GUIContent("Solution", "Warning Solution."),
|
||||||
|
headerTextAlignment = TextAlignment.Center,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
multiColumnHeaderState = new MultiColumnHeaderState(columns);
|
||||||
|
multiColumnHeader = new MultiColumnHeader(multiColumnHeaderState);
|
||||||
|
multiColumnHeader.ResizeToFit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawMenu()
|
||||||
|
{
|
||||||
|
using (new EditorGUILayout.HorizontalScope(EditorStyles.toolbar))
|
||||||
|
{
|
||||||
|
if (GUILayout.Button(EditorGUIUtility.IconContent("Refresh", "Refresh"), EditorStyles.toolbarButton))
|
||||||
|
{
|
||||||
|
LoadValidators();
|
||||||
|
}
|
||||||
|
|
||||||
if (GUILayout.Button(EditorGUIUtility.IconContent("d_Settings", "Select validator"), EditorStyles.toolbarButton))
|
if (GUILayout.Button(EditorGUIUtility.IconContent("d_Settings", "Select validator"), EditorStyles.toolbarButton))
|
||||||
{
|
{
|
||||||
GenericMenu validatorOptionsMenu = new GenericMenu();
|
GenericMenu validatorOptionsMenu = new GenericMenu();
|
||||||
validatorOptionsMenu.AddItem(new GUIContent($"All"), false, OnValidatorInfoVisibilityAllEvent);
|
validatorOptionsMenu.AddItem(new GUIContent($"All"), false, OnValidatorInfoVisibilityAllEvent);
|
||||||
validatorOptionsMenu.AddItem(new GUIContent($"None"), false, OnValidatorInfoVisibilityNoneEvent);
|
validatorOptionsMenu.AddItem(new GUIContent($"None"), false, OnValidatorInfoVisibilityNoneEvent);
|
||||||
validatorOptionsMenu.AddSeparator("");
|
validatorOptionsMenu.AddSeparator("");
|
||||||
foreach (ValidatorInfo validatorInfo in validators)
|
foreach (ValidatorInfo validatorInfo in validators)
|
||||||
{
|
{
|
||||||
validatorOptionsMenu.AddItem(new GUIContent($"{validatorInfo.validator.GetType().Name}"), validatorInfo.isEnabled, OnValidatorInfoVisibilityChangedEvent, validatorInfo);
|
validatorOptionsMenu.AddItem(new GUIContent($"{validatorInfo.validator.MenuName}"), validatorInfo.isEnabled, OnValidatorInfoVisibilityChangedEvent, validatorInfo);
|
||||||
}
|
}
|
||||||
validatorOptionsMenu.ShowAsContext();
|
validatorOptionsMenu.ShowAsContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GUILayout.Button(EditorGUIUtility.IconContent("PlayButton", "Run all"), EditorStyles.toolbarButton))
|
if (GUILayout.Button(EditorGUIUtility.IconContent("PlayButton", "Run all"), EditorStyles.toolbarButton))
|
||||||
{
|
|
||||||
RunValidators();
|
|
||||||
UpdateStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.FlexibleSpace();
|
|
||||||
|
|
||||||
settings.searchInput = GUILayout.TextField(settings.searchInput, EditorStyles.toolbarSearchField, GUILayout.MaxWidth(300));
|
|
||||||
|
|
||||||
if(reportStats != null)
|
|
||||||
{
|
{
|
||||||
settings.showInfo = GUILayout.Toggle(settings.showInfo, new GUIContent($"{reportStats.infoCount}", EditorGUIUtility.IconContent(GetWarningIconName(WarningType.Info)).image), EditorStyles.toolbarButton);
|
RunValidators();
|
||||||
settings.showWarning = GUILayout.Toggle(settings.showWarning, new GUIContent($"{reportStats.warningCount}", EditorGUIUtility.IconContent(GetWarningIconName(WarningType.Warning)).image), EditorStyles.toolbarButton);
|
UpdateStats();
|
||||||
settings.showError = GUILayout.Toggle(settings.showError, new GUIContent($"{reportStats.errorCount}", EditorGUIUtility.IconContent(GetWarningIconName(WarningType.Error)).image), EditorStyles.toolbarButton);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawMultiColumnScope()
|
GUILayout.FlexibleSpace();
|
||||||
{
|
|
||||||
//GUILayout.FlexibleSpace(); // If nothing has been drawn yet, uncomment this because GUILayoutUtility.GetLastRect() needs it.
|
|
||||||
Rect windowRect = GUILayoutUtility.GetLastRect();
|
|
||||||
windowRect.width = position.width;
|
|
||||||
windowRect.height = position.height;
|
|
||||||
|
|
||||||
if (multiColumnHeader == null)
|
settings.searchInput = GUILayout.TextField(settings.searchInput, EditorStyles.toolbarSearchField, GUILayout.MaxWidth(300));
|
||||||
{
|
|
||||||
InitializeMultiColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
float columnHeight = EditorGUIUtility.singleLineHeight * 2;
|
if(reportStats != null)
|
||||||
|
{
|
||||||
|
settings.showInfo = GUILayout.Toggle(settings.showInfo, new GUIContent($"{reportStats.infoCount}", EditorGUIUtility.IconContent(GetWarningIconName(WarningType.Info)).image), EditorStyles.toolbarButton);
|
||||||
|
settings.showWarning = GUILayout.Toggle(settings.showWarning, new GUIContent($"{reportStats.warningCount}", EditorGUIUtility.IconContent(GetWarningIconName(WarningType.Warning)).image), EditorStyles.toolbarButton);
|
||||||
|
settings.showError = GUILayout.Toggle(settings.showError, new GUIContent($"{reportStats.errorCount}", EditorGUIUtility.IconContent(GetWarningIconName(WarningType.Error)).image), EditorStyles.toolbarButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rect headerRect = new Rect(windowRect)
|
private void DrawMultiColumnScope()
|
||||||
{
|
{
|
||||||
height = EditorGUIUtility.singleLineHeight,
|
//GUILayout.FlexibleSpace(); // If nothing has been drawn yet, uncomment this because GUILayoutUtility.GetLastRect() needs it.
|
||||||
};
|
Rect windowRect = GUILayoutUtility.GetLastRect();
|
||||||
|
windowRect.width = position.width;
|
||||||
|
windowRect.height = position.height;
|
||||||
|
|
||||||
Rect scrollViewPositionRect = GUILayoutUtility.GetRect(0, float.MaxValue, 0, float.MaxValue);
|
if (multiColumnHeader == null)
|
||||||
scrollViewPositionRect.y += headerRect.height - EditorGUIUtility.standardVerticalSpacing;
|
|
||||||
scrollViewPositionRect.height -= headerRect.height - EditorGUIUtility.standardVerticalSpacing;
|
|
||||||
|
|
||||||
Rect scrollViewRect = new Rect(windowRect)
|
|
||||||
{
|
|
||||||
width = multiColumnHeaderState.widthOfAllVisibleColumns,
|
|
||||||
height = rows * columnHeight
|
|
||||||
};
|
|
||||||
|
|
||||||
Rect rowRect = new Rect(windowRect)
|
|
||||||
{
|
|
||||||
width = multiColumnHeaderWidth,
|
|
||||||
height = columnHeight,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Draw column header.
|
|
||||||
multiColumnHeader.OnGUI(headerRect, scrollPosition.x);
|
|
||||||
|
|
||||||
// Draw scroll view.
|
|
||||||
using (GUI.ScrollViewScope scope = new GUI.ScrollViewScope(scrollViewPositionRect, scrollPosition, scrollViewRect, false, false))
|
|
||||||
{
|
{
|
||||||
scrollPosition = scope.scrollPosition;
|
InitializeMultiColumn();
|
||||||
multiColumnHeaderWidth = Mathf.Max(scrollViewPositionRect.width + scrollPosition.x, multiColumnHeaderWidth);
|
}
|
||||||
|
|
||||||
rows = 0;
|
float columnHeight = EditorGUIUtility.singleLineHeight * 2;
|
||||||
for (int i = 0; i < reports.Count; i++)
|
|
||||||
{
|
Rect headerRect = new Rect(windowRect)
|
||||||
for (int j = 0; j < reports[i].Reports.Count; j++)
|
{
|
||||||
{
|
height = EditorGUIUtility.singleLineHeight,
|
||||||
// Type filter.
|
};
|
||||||
|
|
||||||
|
Rect scrollViewPositionRect = GUILayoutUtility.GetRect(0, float.MaxValue, 0, float.MaxValue);
|
||||||
|
scrollViewPositionRect.y += headerRect.height - EditorGUIUtility.standardVerticalSpacing;
|
||||||
|
scrollViewPositionRect.height -= headerRect.height - EditorGUIUtility.standardVerticalSpacing;
|
||||||
|
|
||||||
|
Rect scrollViewRect = new Rect(windowRect)
|
||||||
|
{
|
||||||
|
width = multiColumnHeaderState.widthOfAllVisibleColumns,
|
||||||
|
height = rows * columnHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
Rect rowRect = new Rect(windowRect)
|
||||||
|
{
|
||||||
|
width = multiColumnHeaderWidth,
|
||||||
|
height = columnHeight,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Draw column header.
|
||||||
|
multiColumnHeader.OnGUI(headerRect, scrollPosition.x);
|
||||||
|
|
||||||
|
// Draw scroll view.
|
||||||
|
using (GUI.ScrollViewScope scope = new GUI.ScrollViewScope(scrollViewPositionRect, scrollPosition, scrollViewRect, false, false))
|
||||||
|
{
|
||||||
|
scrollPosition = scope.scrollPosition;
|
||||||
|
multiColumnHeaderWidth = Mathf.Max(scrollViewPositionRect.width + scrollPosition.x, multiColumnHeaderWidth);
|
||||||
|
|
||||||
|
rows = 0;
|
||||||
|
for (int i = 0; i < reports.Count; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < reports[i].Reports.Count; j++)
|
||||||
|
{
|
||||||
|
// Type filter.
|
||||||
switch (reports[i].Reports[j].WarningType)
|
switch (reports[i].Reports[j].WarningType)
|
||||||
{
|
{
|
||||||
case WarningType.Info:
|
case WarningType.Info:
|
||||||
if (!settings.showInfo)
|
if (!settings.showInfo)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case WarningType.Warning:
|
case WarningType.Warning:
|
||||||
if (!settings.showWarning)
|
if (!settings.showWarning)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case WarningType.Error:
|
case WarningType.Error:
|
||||||
if (!settings.showError)
|
if (!settings.showError)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search filter.
|
// Search filter.
|
||||||
if (!string.IsNullOrWhiteSpace(settings.searchInput))
|
if (!string.IsNullOrWhiteSpace(settings.searchInput))
|
||||||
{
|
{
|
||||||
if (!reports[i].Reports[j].Category.Contains(settings.searchInput) && !reports[i].Reports[j].Message.Contains(settings.searchInput) && !reports[i].Reports[j].Solution.Contains(settings.searchInput))
|
if (!reports[i].Reports[j].Category.Contains(settings.searchInput) && !reports[i].Reports[j].Message.Contains(settings.searchInput) && !reports[i].Reports[j].Solution.Contains(settings.searchInput))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only draw what is visible within the view.
|
// Only draw what is visible within the view.
|
||||||
if (rowRect.yMax > windowRect.y + scrollPosition.y && rowRect.yMin < windowRect.height + scrollPosition.y)
|
if (rowRect.yMax > windowRect.y + scrollPosition.y && rowRect.yMin < windowRect.height + scrollPosition.y)
|
||||||
{
|
{
|
||||||
if (rows % 2 == 0)
|
if (rows % 2 == 0)
|
||||||
{
|
{
|
||||||
EditorGUI.DrawRect(rowRect, settings.darkColor);
|
EditorGUI.DrawRect(rowRect, settings.darkColor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EditorGUI.DrawRect(rowRect, settings.lightColor);
|
EditorGUI.DrawRect(rowRect, settings.lightColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning Field.
|
// Warning Field.
|
||||||
int columnIndex = 0;
|
int columnIndex = 0;
|
||||||
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
||||||
{
|
{
|
||||||
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
||||||
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
||||||
columnRect.y = rowRect.y;
|
columnRect.y = rowRect.y;
|
||||||
columnRect.height = rowRect.height;
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
||||||
labelFieldRect.x += 9;
|
labelFieldRect.x += 9;
|
||||||
labelFieldRect.width -= 9;
|
labelFieldRect.width -= 9;
|
||||||
|
|
||||||
EditorGUI.LabelField(
|
EditorGUI.LabelField(
|
||||||
labelFieldRect,
|
labelFieldRect,
|
||||||
EditorGUIUtility.IconContent(GetWarningIconName(reports[i].Reports[j].WarningType), $"{reports[i].Reports[j].WarningType}")
|
EditorGUIUtility.IconContent(GetWarningIconName(reports[i].Reports[j].WarningType), $"{reports[i].Reports[j].WarningType}")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Target Field.
|
// Target Field.
|
||||||
columnIndex = 1;
|
columnIndex = 1;
|
||||||
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
||||||
{
|
{
|
||||||
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
||||||
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
||||||
columnRect.y = rowRect.y;
|
columnRect.y = rowRect.y;
|
||||||
columnRect.height = rowRect.height;
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
if(reports[i].Reports[j].Target != null)
|
if(reports[i].Reports[j].Target != null)
|
||||||
{
|
{
|
||||||
if (GUI.Button(
|
if (GUI.Button(
|
||||||
multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect),
|
multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect),
|
||||||
EditorGUIUtility.IconContent("Animation.FilterBySelection", "Ping Object")
|
EditorGUIUtility.IconContent("Animation.FilterBySelection", "Ping Object")
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
Selection.objects = new Object[] { reports[i].Reports[j].Target };
|
Selection.objects = new Object[] { reports[i].Reports[j].Target };
|
||||||
|
|
||||||
if (!Selection.activeObject)
|
if (!Selection.activeObject)
|
||||||
{
|
{
|
||||||
Debug.Log($"{nameof(Selection.activeObject)} is null.");
|
Debug.Log($"{nameof(Selection.activeObject)} is null.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Object o in Selection.objects)
|
foreach (Object o in Selection.objects)
|
||||||
{
|
{
|
||||||
EditorGUIUtility.PingObject(o);
|
EditorGUIUtility.PingObject(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category Field.
|
// Category Field.
|
||||||
columnIndex = 2;
|
columnIndex = 2;
|
||||||
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
||||||
{
|
{
|
||||||
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
||||||
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
||||||
columnRect.y = rowRect.y;
|
columnRect.y = rowRect.y;
|
||||||
columnRect.height = rowRect.height;
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
||||||
labelFieldRect.x += 7;
|
labelFieldRect.x += 7;
|
||||||
labelFieldRect.width -= 7;
|
labelFieldRect.width -= 7;
|
||||||
|
|
||||||
EditorGUI.LabelField(
|
EditorGUI.LabelField(
|
||||||
labelFieldRect,
|
labelFieldRect,
|
||||||
new GUIContent($"{reports[i].Reports[j].Category}")
|
new GUIContent($"{reports[i].Reports[j].Category}")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message Field.
|
// Message Field.
|
||||||
columnIndex = 3;
|
columnIndex = 3;
|
||||||
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
||||||
{
|
{
|
||||||
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
||||||
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
||||||
columnRect.y = rowRect.y;
|
columnRect.y = rowRect.y;
|
||||||
columnRect.height = rowRect.height;
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
||||||
labelFieldRect.x += 7;
|
labelFieldRect.x += 7;
|
||||||
labelFieldRect.width -= 7;
|
labelFieldRect.width -= 7;
|
||||||
|
|
||||||
EditorGUI.LabelField(
|
EditorGUI.LabelField(
|
||||||
labelFieldRect,
|
labelFieldRect,
|
||||||
new GUIContent($"{reports[i].Reports[j].Message}")
|
new GUIContent($"{reports[i].Reports[j].Message}")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solution Field.
|
// Solution Field.
|
||||||
columnIndex = 4;
|
columnIndex = 4;
|
||||||
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
if (multiColumnHeader.IsColumnVisible(columnIndex))
|
||||||
{
|
{
|
||||||
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex);
|
||||||
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex);
|
||||||
columnRect.y = rowRect.y;
|
columnRect.y = rowRect.y;
|
||||||
columnRect.height = rowRect.height;
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex, columnRect);
|
||||||
labelFieldRect.x += 7;
|
labelFieldRect.x += 7;
|
||||||
labelFieldRect.width -= 7;
|
labelFieldRect.width -= 7;
|
||||||
|
|
||||||
EditorGUI.LabelField(
|
EditorGUI.LabelField(
|
||||||
labelFieldRect,
|
labelFieldRect,
|
||||||
new GUIContent($"{reports[i].Reports[j].Solution}")
|
new GUIContent($"{reports[i].Reports[j].Solution}")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rowRect.y += columnHeight;
|
rowRect.y += columnHeight;
|
||||||
rows++;
|
rows++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scope.handleScrollWheel = true;
|
scope.handleScrollWheel = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadValidators()
|
|
||||||
{
|
|
||||||
for (int i = validators.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (validators[i].validator == null)
|
|
||||||
{
|
|
||||||
validators.RemoveAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Type type in GetValidatorTypes())
|
|
||||||
{
|
|
||||||
bool hasValidator = false;
|
|
||||||
foreach (ValidatorInfo validatorInfo in validators)
|
|
||||||
{
|
|
||||||
if (validatorInfo.validator.GetType() == type)
|
|
||||||
{
|
|
||||||
hasValidator = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValidator)
|
|
||||||
{
|
|
||||||
IValidator validator = (IValidator)Activator.CreateInstance(type);
|
|
||||||
if (validator != null)
|
|
||||||
{
|
|
||||||
validators.Add(new ValidatorInfo(validator));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RunValidators()
|
|
||||||
{
|
|
||||||
reports.Clear();
|
|
||||||
|
|
||||||
foreach (ValidatorInfo validatorInfo in validators)
|
|
||||||
{
|
|
||||||
if (validatorInfo.isEnabled)
|
|
||||||
{
|
|
||||||
reports.Add(validatorInfo.validator.Validate());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateStats()
|
private void LoadValidators()
|
||||||
{
|
{
|
||||||
reportStats = new ReportStats();
|
for (int i = validators.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (validators[i].validator == null)
|
||||||
|
{
|
||||||
|
validators.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Type type in GetValidatorTypes())
|
||||||
|
{
|
||||||
|
bool hasValidator = false;
|
||||||
|
foreach (ValidatorInfo validatorInfo in validators)
|
||||||
|
{
|
||||||
|
if (validatorInfo.validator.GetType() == type)
|
||||||
|
{
|
||||||
|
hasValidator = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidator)
|
||||||
|
{
|
||||||
|
IValidator validator = (IValidator)Activator.CreateInstance(type);
|
||||||
|
if (validator != null)
|
||||||
|
{
|
||||||
|
validators.Add(new ValidatorInfo(validator));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RunValidators()
|
||||||
|
{
|
||||||
|
reports.Clear();
|
||||||
|
|
||||||
|
foreach (ValidatorInfo validatorInfo in validators)
|
||||||
|
{
|
||||||
|
if (validatorInfo.isEnabled)
|
||||||
|
{
|
||||||
|
reports.Add(validatorInfo.validator.Validate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStats()
|
||||||
|
{
|
||||||
|
reportStats = new ReportStats();
|
||||||
|
|
||||||
foreach (Report report in reports)
|
foreach (Report report in reports)
|
||||||
{
|
{
|
||||||
@ -442,7 +442,7 @@ namespace Validator.Editor
|
|||||||
switch (report.Reports[i].WarningType)
|
switch (report.Reports[i].WarningType)
|
||||||
{
|
{
|
||||||
case WarningType.Info:
|
case WarningType.Info:
|
||||||
reportStats.infoCount++;
|
reportStats.infoCount++;
|
||||||
break;
|
break;
|
||||||
case WarningType.Warning:
|
case WarningType.Warning:
|
||||||
reportStats.warningCount++;
|
reportStats.warningCount++;
|
||||||
@ -451,26 +451,26 @@ namespace Validator.Editor
|
|||||||
reportStats.errorCount++;
|
reportStats.errorCount++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnValidatorInfoVisibilityChangedEvent(object info)
|
private void OnValidatorInfoVisibilityChangedEvent(object info)
|
||||||
{
|
{
|
||||||
if(info is ValidatorInfo validatorInfo)
|
if(info is ValidatorInfo validatorInfo)
|
||||||
{
|
{
|
||||||
validatorInfo.isEnabled = !validatorInfo.isEnabled;
|
validatorInfo.isEnabled = !validatorInfo.isEnabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnValidatorInfoVisibilityAllEvent()
|
private void OnValidatorInfoVisibilityAllEvent()
|
||||||
{
|
{
|
||||||
foreach (ValidatorInfo validatorInfo in validators)
|
foreach (ValidatorInfo validatorInfo in validators)
|
||||||
{
|
{
|
||||||
validatorInfo.isEnabled = true;
|
validatorInfo.isEnabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnValidatorInfoVisibilityNoneEvent()
|
private void OnValidatorInfoVisibilityNoneEvent()
|
||||||
@ -483,10 +483,10 @@ namespace Validator.Editor
|
|||||||
|
|
||||||
private static Type[] GetValidatorTypes()
|
private static Type[] GetValidatorTypes()
|
||||||
{
|
{
|
||||||
return TypeCache.GetTypesDerivedFrom<IValidator>().ToArray();
|
return TypeCache.GetTypesDerivedFrom<IValidator>().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetWarningIconName(WarningType warningType)
|
private static string GetWarningIconName(WarningType warningType)
|
||||||
{
|
{
|
||||||
return warningType switch
|
return warningType switch
|
||||||
{
|
{
|
||||||
|
79
Editor/Validators/RequiredAttributeValidator.cs
Normal file
79
Editor/Validators/RequiredAttributeValidator.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Validator.Editor
|
||||||
|
{
|
||||||
|
public class RequiredAttributeAssetValidator : IValidator
|
||||||
|
{
|
||||||
|
public string MenuName => nameof(RequiredAttributeAssetValidator);
|
||||||
|
|
||||||
|
private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||||
|
|
||||||
|
public Report Validate()
|
||||||
|
{
|
||||||
|
Report report = new Report(nameof(RequiredAttributeAssetValidator));
|
||||||
|
|
||||||
|
List<Object> objects = ValidatableAssetValidator.FindAssetsByType<Object>();
|
||||||
|
|
||||||
|
for (int i = 0; i < objects.Count; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("RequiredAttributeAssetValidator", "RequiredAttribute...", (float)i / objects.Count);
|
||||||
|
|
||||||
|
IEnumerable<(FieldInfo FieldInfo, RequiredAttribute Attribute)> fieldsWithRequiredAttribute = from fi in objects[i].GetType().GetFields(flags)
|
||||||
|
let attr = fi.GetCustomAttributes(typeof(RequiredAttribute), true)
|
||||||
|
where attr.Length == 1
|
||||||
|
select (FieldInfo: fi, Attribute: attr.First() as RequiredAttribute);
|
||||||
|
|
||||||
|
foreach ((FieldInfo FieldInfo, RequiredAttribute Attribute) field in fieldsWithRequiredAttribute)
|
||||||
|
{
|
||||||
|
object o = field.FieldInfo.GetValue(objects[i]);
|
||||||
|
if (o == null || o.Equals(null))
|
||||||
|
{
|
||||||
|
report.Log(objects[i], field.Attribute.WarningType, field.Attribute.Category, $"{field.FieldInfo.Name} is null", $"Assign {field.FieldInfo.FieldType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RequiredAttributeSceneValidator : IValidator
|
||||||
|
{
|
||||||
|
public string MenuName => nameof(RequiredAttributeSceneValidator);
|
||||||
|
|
||||||
|
private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||||
|
|
||||||
|
public Report Validate()
|
||||||
|
{
|
||||||
|
Report report = new Report(nameof(RequiredAttributeSceneValidator));
|
||||||
|
|
||||||
|
List<MonoBehaviour> objects = ValidatableSceneValidator.FindAllObjectsOfType<MonoBehaviour>();
|
||||||
|
|
||||||
|
for (int i = 0; i < objects.Count; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("RequiredAttributeSceneValidator", "RequiredAttribute...", (float)i / objects.Count);
|
||||||
|
IEnumerable<(FieldInfo FieldInfo, RequiredAttribute Attribute)> fieldsWithRequiredAttribute = from fi in objects[i].GetType().GetFields(flags)
|
||||||
|
let attr = fi.GetCustomAttributes(typeof(RequiredAttribute), true)
|
||||||
|
where attr.Length == 1
|
||||||
|
select (FieldInfo: fi, Attribute: attr.First() as RequiredAttribute);
|
||||||
|
|
||||||
|
foreach ((FieldInfo FieldInfo, RequiredAttribute Attribute) field in fieldsWithRequiredAttribute)
|
||||||
|
{
|
||||||
|
object o = field.FieldInfo.GetValue(objects[i]);
|
||||||
|
if (o == null || o.Equals(null))
|
||||||
|
{
|
||||||
|
report.Log(objects[i], field.Attribute.WarningType, field.Attribute.Category, $"{field.FieldInfo.Name} is null", $"Assign {field.FieldInfo.FieldType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Editor/Validators/RequiredAttributeValidator.cs.meta
Normal file
11
Editor/Validators/RequiredAttributeValidator.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 90d5c1b8964451644b0aa09257ab0bc3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,55 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
|
|
||||||
namespace Validator.Editor
|
|
||||||
{
|
|
||||||
public class SceneValidator : IValidator
|
|
||||||
{
|
|
||||||
public Report Validate()
|
|
||||||
{
|
|
||||||
Report report = new Report("SceneValidator");
|
|
||||||
|
|
||||||
List<IValidatable> objects = FindAllObjectsOfType<IValidatable>();
|
|
||||||
for (int i = 0; i < objects.Count; i++)
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayProgressBar("SceneValidator", "Validate...", (float)i / objects.Count);
|
|
||||||
|
|
||||||
objects[i].Validate(report);
|
|
||||||
}
|
|
||||||
EditorUtility.ClearProgressBar();
|
|
||||||
|
|
||||||
return report;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<GameObject> GetAllRootGameObjects()
|
|
||||||
{
|
|
||||||
List<GameObject> gameObjects = new List<GameObject>();
|
|
||||||
|
|
||||||
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayProgressBar("SceneValidator", "GetAllRootGameObjects...", (float)i / SceneManager.sceneCount);
|
|
||||||
gameObjects.AddRange(SceneManager.GetSceneAt(i).GetRootGameObjects());
|
|
||||||
}
|
|
||||||
EditorUtility.ClearProgressBar();
|
|
||||||
|
|
||||||
return gameObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<T> FindAllObjectsOfType<T>()
|
|
||||||
{
|
|
||||||
List<T> objects = new List<T>();
|
|
||||||
|
|
||||||
List<GameObject> gameObjects = GetAllRootGameObjects();
|
|
||||||
for (int i = 0; i < gameObjects.Count; i++)
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayProgressBar("SceneValidator", "FindAllObjectsOfType...", (float)i / gameObjects.Count);
|
|
||||||
objects.AddRange(gameObjects[i].GetComponentsInChildren<T>(true));
|
|
||||||
}
|
|
||||||
EditorUtility.ClearProgressBar();
|
|
||||||
|
|
||||||
return objects;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,11 +4,13 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Validator.Editor
|
namespace Validator.Editor
|
||||||
{
|
{
|
||||||
public class AssetValidator : IValidator
|
public class ValidatableAssetValidator : IValidator
|
||||||
{
|
{
|
||||||
|
public string MenuName => nameof(ValidatableAssetValidator);
|
||||||
|
|
||||||
public Report Validate()
|
public Report Validate()
|
||||||
{
|
{
|
||||||
Report report = new Report("AssetValidator");
|
Report report = new Report(nameof(ValidatableAssetValidator));
|
||||||
|
|
||||||
List<Object> objects = FindAssetsByType<Object>();
|
List<Object> objects = FindAssetsByType<Object>();
|
||||||
for (int i = 0; i < objects.Count; i++)
|
for (int i = 0; i < objects.Count; i++)
|
57
Editor/Validators/ValidatableSceneValidator.cs
Normal file
57
Editor/Validators/ValidatableSceneValidator.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace Validator.Editor
|
||||||
|
{
|
||||||
|
public class ValidatableSceneValidator : IValidator
|
||||||
|
{
|
||||||
|
public string MenuName => nameof(ValidatableSceneValidator);
|
||||||
|
|
||||||
|
public Report Validate()
|
||||||
|
{
|
||||||
|
Report report = new Report(nameof(ValidatableSceneValidator));
|
||||||
|
|
||||||
|
List<IValidatable> objects = FindAllObjectsOfType<IValidatable>();
|
||||||
|
for (int i = 0; i < objects.Count; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("SceneValidator", "Validate...", (float)i / objects.Count);
|
||||||
|
|
||||||
|
objects[i].Validate(report);
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<GameObject> GetAllRootGameObjects()
|
||||||
|
{
|
||||||
|
List<GameObject> gameObjects = new List<GameObject>();
|
||||||
|
|
||||||
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("SceneValidator", "GetAllRootGameObjects...", (float)i / SceneManager.sceneCount);
|
||||||
|
gameObjects.AddRange(SceneManager.GetSceneAt(i).GetRootGameObjects());
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return gameObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<T> FindAllObjectsOfType<T>()
|
||||||
|
{
|
||||||
|
List<T> objects = new List<T>();
|
||||||
|
|
||||||
|
List<GameObject> gameObjects = GetAllRootGameObjects();
|
||||||
|
for (int i = 0; i < gameObjects.Count; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("SceneValidator", "FindAllObjectsOfType...", (float)i / gameObjects.Count);
|
||||||
|
objects.AddRange(gameObjects[i].GetComponentsInChildren<T>(true));
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
README.md
27
README.md
@ -1,12 +1,11 @@
|
|||||||
# Validator
|
# Validator
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Unity project validator framework.
|
Unity project validator framework.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
Open Validator Window:
|
Add a custom validate check using the `IValidatable` interface:
|
||||||
> Window -> General -> Validator
|
|
||||||
|
|
||||||
Add validatable:
|
|
||||||
```C#
|
```C#
|
||||||
using Validator;
|
using Validator;
|
||||||
|
|
||||||
@ -17,10 +16,10 @@ public class MyBehaviour : MonoBehaviour, IValidatable
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
public void Validate(Report report)
|
public void Validate(Report report)
|
||||||
{
|
{
|
||||||
// Check if health is valid.
|
// Check if health is valid.
|
||||||
if(startHealth <= 0)
|
if(startHealth <= 0)
|
||||||
{
|
{
|
||||||
// If not, log it.
|
// If not, log it.
|
||||||
report.Log(this, WarningType.Warning, ReportCategories.Design, $"{nameof(startHealth)} is to low", $"Make value > 0");
|
report.Log(this, WarningType.Warning, ReportCategories.Design, $"{nameof(startHealth)} is to low", $"Make value > 0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,13 +27,21 @@ public class MyBehaviour : MonoBehaviour, IValidatable
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Add a validate check using `[Required]` attribute:
|
||||||
|
```C#
|
||||||
|
[SerializeField, Required] private GameObject playerPrefab = null; // If someone forgets to assign it, it would be invalid.
|
||||||
|
```
|
||||||
|
|
||||||
|
Open Validator Window:
|
||||||
|
> Window -> General -> Validator
|
||||||
|
|
||||||
|
Run the validator:
|
||||||
|
> Click the 'run/play' button and wait for the report to be generated.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
[Installing from a Git URL](https://docs.unity3d.com/Manual/upm-ui-giturl.html)
|
[Installing from a Git URL](https://docs.unity3d.com/Manual/upm-ui-giturl.html)
|
||||||
|
|
||||||
[Unitypackage](https://github.com/COMPANYNAME/PACKAGENAME/releases)
|
|
||||||
|
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
Overall package is licensed under [MIT](/LICENSE.md), unless otherwise noted in the [3rd party licenses](/THIRD%20PARTY%20NOTICES.md) file and/or source code.
|
Overall package is licensed under [MIT](/LICENSE.md), unless otherwise noted in the [3rd party licenses](/THIRD%20PARTY%20NOTICES.md) file and/or source code.
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
namespace Validator
|
namespace Validator
|
||||||
{
|
{
|
||||||
public static partial class ReportCategories
|
public static partial class ReportCategories
|
||||||
{
|
{
|
||||||
public const string Art = "Art";
|
public const string Art = "Art";
|
||||||
public const string Design = "Design";
|
public const string Design = "Design";
|
||||||
public const string Code = "Code";
|
public const string Code = "Code";
|
||||||
}
|
}
|
||||||
}
|
}
|
8
Runtime/Validators.meta
Normal file
8
Runtime/Validators.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8cd25e23ad137e24ea0f469556831712
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Runtime/Validators/Attributes.meta
Normal file
8
Runtime/Validators/Attributes.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 25705f09a21a10049aed213ea301db84
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
19
Runtime/Validators/Attributes/RequiredAttribute.cs
Normal file
19
Runtime/Validators/Attributes/RequiredAttribute.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Validator
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
|
||||||
|
public class RequiredAttribute : Attribute
|
||||||
|
{
|
||||||
|
public WarningType WarningType { get; private set; } = WarningType.Error;
|
||||||
|
public string Category { get; private set; } = ReportCategories.Design;
|
||||||
|
|
||||||
|
public RequiredAttribute() { }
|
||||||
|
|
||||||
|
public RequiredAttribute(WarningType warningType = WarningType.Error, string category = ReportCategories.Design)
|
||||||
|
{
|
||||||
|
WarningType = warningType;
|
||||||
|
Category = category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Runtime/Validators/Attributes/RequiredAttribute.cs.meta
Normal file
11
Runtime/Validators/Attributes/RequiredAttribute.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4dbbb107f0e849140b1132ac5dcca90f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "com.vertexcolor.validator",
|
"name": "com.vertexcolor.validator",
|
||||||
"displayName": "Validator",
|
"displayName": "Validator",
|
||||||
"version": "0.1.1",
|
"version": "0.1.4",
|
||||||
"unity": "2019.3",
|
"unity": "2019.3",
|
||||||
"description": "Unity project validator framework.",
|
"description": "Unity project validator framework.",
|
||||||
"category": "Tool",
|
"category": "Tool",
|
||||||
|
Reference in New Issue
Block a user