mirror of
https://github.com/maxartz15/Validator.git
synced 2024-11-23 12:35:32 +01:00
Base validator
SceneValidator & AssetValidator of objects that implement IValidatable.
This commit is contained in:
parent
071e15c2be
commit
4b9b5a8c1d
@ -1,6 +1,3 @@
|
|||||||
# Change Log:
|
# Change Log:
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1.0
|
||||||
|
- Base validator framework.
|
||||||
- Start Project:
|
|
||||||
- ...
|
|
7
CHANGELOG.md.meta
Normal file
7
CHANGELOG.md.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 12174dcb2c74c6f4eb0f6d28d8670c14
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,3 +1,3 @@
|
|||||||
# PACKAGENAME
|
# Validator
|
||||||
|
|
||||||
Documentation.
|
Documentation.
|
8
Editor.meta
Normal file
8
Editor.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 27a6e9d765504c6449f6cb83c81f2353
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "COMPANYNAME.PACKAGENAME.Editor",
|
|
||||||
"references": [
|
|
||||||
"COMPANYNAME.PACKAGENAME"
|
|
||||||
],
|
|
||||||
"includePlatforms": [
|
|
||||||
"Editor"
|
|
||||||
],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": false,
|
|
||||||
"overrideReferences": false,
|
|
||||||
"precompiledReferences": [],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [],
|
|
||||||
"versionDefines": []
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEditor;
|
|
||||||
|
|
||||||
namespace COMPANYNAME.PACKAGENAME.Editor
|
|
||||||
{
|
|
||||||
}
|
|
7
Editor/IValidator.cs
Normal file
7
Editor/IValidator.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Validator.Editor
|
||||||
|
{
|
||||||
|
public interface IValidator
|
||||||
|
{
|
||||||
|
public Report Validate();
|
||||||
|
}
|
||||||
|
}
|
11
Editor/IValidator.cs.meta
Normal file
11
Editor/IValidator.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 75a64c845d92d1548bb095b40a6f5c9f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
381
Editor/ValidatorEditorWindow.cs
Normal file
381
Editor/ValidatorEditorWindow.cs
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.IMGUI.Controls;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace Validator.Editor
|
||||||
|
{
|
||||||
|
public class ValidatorEditorWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private readonly List<Report> reports = new List<Report>();
|
||||||
|
private readonly List<IValidator> validators = new List<IValidator>();
|
||||||
|
|
||||||
|
private MultiColumnHeaderState multiColumnHeaderState;
|
||||||
|
private MultiColumnHeader multiColumnHeader;
|
||||||
|
private MultiColumnHeaderState.Column[] columns;
|
||||||
|
private readonly Color lightColor = Color.white * 0.3f;
|
||||||
|
private readonly Color darkColor = Color.white * 0.1f;
|
||||||
|
private Vector2 scrollPosition;
|
||||||
|
private float multiColumnHeaderWidth;
|
||||||
|
private float rows;
|
||||||
|
|
||||||
|
[MenuItem("Window/General/Validator")]
|
||||||
|
private static void Init()
|
||||||
|
{
|
||||||
|
ValidatorEditorWindow window = (ValidatorEditorWindow)GetWindow(typeof(ValidatorEditorWindow));
|
||||||
|
window.titleContent = new GUIContent("Validator");
|
||||||
|
window.Show();
|
||||||
|
window.LoadValidators();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
using (new EditorGUILayout.VerticalScope(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)))
|
||||||
|
{
|
||||||
|
using (new EditorGUILayout.HorizontalScope())
|
||||||
|
{
|
||||||
|
if (GUILayout.Button(EditorGUIUtility.IconContent("Refresh", "Refresh")))
|
||||||
|
{
|
||||||
|
LoadValidators();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button(EditorGUIUtility.IconContent("PlayButton", "Run all")))
|
||||||
|
{
|
||||||
|
reports.Clear();
|
||||||
|
|
||||||
|
foreach (IValidator validator in validators)
|
||||||
|
{
|
||||||
|
reports.Add(validator.Validate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button(EditorGUIUtility.IconContent("d_preAudioLoopOff", "Select validator")))
|
||||||
|
{
|
||||||
|
GenericMenu validatorOptionsMenu = new GenericMenu();
|
||||||
|
foreach (IValidator validator in validators)
|
||||||
|
{
|
||||||
|
validatorOptionsMenu.AddItem(new GUIContent($"{validator.GetType().Name}"), false, OnGenericValidate, validator);
|
||||||
|
}
|
||||||
|
validatorOptionsMenu.ShowAsContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
GUILayout.Label($"{reports.Count}/{validators.Count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
|
||||||
|
DrawMultiColumnScope();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeMultiColumn()
|
||||||
|
{
|
||||||
|
columns = new MultiColumnHeaderState.Column[]
|
||||||
|
{
|
||||||
|
new MultiColumnHeaderState.Column()
|
||||||
|
{
|
||||||
|
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: this.columns);
|
||||||
|
multiColumnHeader = new MultiColumnHeader(state: this.multiColumnHeaderState);
|
||||||
|
|
||||||
|
// When we chagne visibility of the column we resize columns to fit in the window.
|
||||||
|
//multiColumnHeader.visibleColumnsChanged += (multiColumnHeader) => multiColumnHeader.ResizeToFit();
|
||||||
|
// Initial resizing of the content.
|
||||||
|
multiColumnHeader.ResizeToFit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawMultiColumnScope()
|
||||||
|
{
|
||||||
|
GUILayout.FlexibleSpace();
|
||||||
|
Rect windowRect = GUILayoutUtility.GetLastRect();
|
||||||
|
windowRect.width = position.width;
|
||||||
|
windowRect.height = position.height;
|
||||||
|
|
||||||
|
if (multiColumnHeader == null)
|
||||||
|
{
|
||||||
|
InitializeMultiColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
float columnHeight = EditorGUIUtility.singleLineHeight * 2;
|
||||||
|
|
||||||
|
Rect headerRect = new Rect(source: windowRect)
|
||||||
|
{
|
||||||
|
height = EditorGUIUtility.singleLineHeight,
|
||||||
|
};
|
||||||
|
|
||||||
|
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(source: windowRect)
|
||||||
|
{
|
||||||
|
width = multiColumnHeaderState.widthOfAllVisibleColumns,
|
||||||
|
height = rows * columnHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
Rect rowRect = new Rect(source: windowRect)
|
||||||
|
{
|
||||||
|
width = multiColumnHeaderWidth,
|
||||||
|
height = columnHeight,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Draw column header.
|
||||||
|
multiColumnHeader.OnGUI(rect: headerRect, xScroll: 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++)
|
||||||
|
{
|
||||||
|
// Only draw what is visable within the view.
|
||||||
|
if (rowRect.yMax > windowRect.y + scrollPosition.y && rowRect.yMin < windowRect.height + scrollPosition.y)
|
||||||
|
{
|
||||||
|
if (j % 2 == 0)
|
||||||
|
{
|
||||||
|
EditorGUI.DrawRect(rect: rowRect, color: darkColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUI.DrawRect(rect: rowRect, color: lightColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning Field.
|
||||||
|
int columnIndex = 0;
|
||||||
|
if (multiColumnHeader.IsColumnVisible(columnIndex: columnIndex))
|
||||||
|
{
|
||||||
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex: columnIndex);
|
||||||
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex: visibleColumnIndex);
|
||||||
|
columnRect.y = rowRect.y;
|
||||||
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex: visibleColumnIndex, columnRect);
|
||||||
|
labelFieldRect.x += 9;
|
||||||
|
labelFieldRect.width -= 9;
|
||||||
|
|
||||||
|
EditorGUI.LabelField(
|
||||||
|
position: labelFieldRect,
|
||||||
|
label: EditorGUIUtility.IconContent(GetWarningIconName(reports[i].Reports[j].WarningType), $"{reports[i].Reports[j].WarningType}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target Field.
|
||||||
|
columnIndex = 1;
|
||||||
|
if (multiColumnHeader.IsColumnVisible(columnIndex: columnIndex))
|
||||||
|
{
|
||||||
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex: columnIndex);
|
||||||
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex: visibleColumnIndex);
|
||||||
|
columnRect.y = rowRect.y;
|
||||||
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
|
if(reports[i].Reports[j].Target != null)
|
||||||
|
{
|
||||||
|
if (GUI.Button(
|
||||||
|
position: multiColumnHeader.GetCellRect(visibleColumnIndex: visibleColumnIndex, columnRect),
|
||||||
|
content: EditorGUIUtility.IconContent("Animation.FilterBySelection", "Ping Object")
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Selection.objects = new Object[] { reports[i].Reports[j].Target };
|
||||||
|
|
||||||
|
if (!Selection.activeObject)
|
||||||
|
{
|
||||||
|
Debug.Log($"{nameof(Selection.activeObject)} is null.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Object o in Selection.objects)
|
||||||
|
{
|
||||||
|
EditorGUIUtility.PingObject(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Category Field.
|
||||||
|
columnIndex = 2;
|
||||||
|
if (multiColumnHeader.IsColumnVisible(columnIndex: columnIndex))
|
||||||
|
{
|
||||||
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex: columnIndex);
|
||||||
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex: visibleColumnIndex);
|
||||||
|
columnRect.y = rowRect.y;
|
||||||
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex: visibleColumnIndex, columnRect);
|
||||||
|
labelFieldRect.x += 7;
|
||||||
|
labelFieldRect.width -= 7;
|
||||||
|
|
||||||
|
EditorGUI.LabelField(
|
||||||
|
position: labelFieldRect,
|
||||||
|
label: new GUIContent($"{reports[i].Reports[j].Category}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message Field.
|
||||||
|
columnIndex = 3;
|
||||||
|
if (multiColumnHeader.IsColumnVisible(columnIndex: columnIndex))
|
||||||
|
{
|
||||||
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex: columnIndex);
|
||||||
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex: visibleColumnIndex);
|
||||||
|
columnRect.y = rowRect.y;
|
||||||
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex: visibleColumnIndex, columnRect);
|
||||||
|
labelFieldRect.x += 7;
|
||||||
|
labelFieldRect.width -= 7;
|
||||||
|
|
||||||
|
EditorGUI.LabelField(
|
||||||
|
position: labelFieldRect,
|
||||||
|
label: new GUIContent($"{reports[i].Reports[j].Message}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solution Field.
|
||||||
|
columnIndex = 4;
|
||||||
|
if (multiColumnHeader.IsColumnVisible(columnIndex: columnIndex))
|
||||||
|
{
|
||||||
|
int visibleColumnIndex = multiColumnHeader.GetVisibleColumnIndex(columnIndex: columnIndex);
|
||||||
|
Rect columnRect = multiColumnHeader.GetColumnRect(visibleColumnIndex: visibleColumnIndex);
|
||||||
|
columnRect.y = rowRect.y;
|
||||||
|
columnRect.height = rowRect.height;
|
||||||
|
|
||||||
|
Rect labelFieldRect = multiColumnHeader.GetCellRect(visibleColumnIndex: visibleColumnIndex, columnRect);
|
||||||
|
labelFieldRect.x += 7;
|
||||||
|
labelFieldRect.width -= 7;
|
||||||
|
|
||||||
|
EditorGUI.LabelField(
|
||||||
|
position: labelFieldRect,
|
||||||
|
label: new GUIContent($"{reports[i].Reports[j].Solution}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rowRect.y += columnHeight;
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope.handleScrollWheel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadValidators()
|
||||||
|
{
|
||||||
|
for (int i = validators.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (validators[i] == null)
|
||||||
|
{
|
||||||
|
validators.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Type type in GetValidatorTypes())
|
||||||
|
{
|
||||||
|
bool hasValidator = false;
|
||||||
|
foreach (IValidator validator in validators)
|
||||||
|
{
|
||||||
|
if (validator.GetType() == type)
|
||||||
|
{
|
||||||
|
hasValidator = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidator)
|
||||||
|
{
|
||||||
|
IValidator validator = (IValidator)Activator.CreateInstance(type);
|
||||||
|
if (validator != null)
|
||||||
|
{
|
||||||
|
validators.Add(validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGenericValidate(object validator)
|
||||||
|
{
|
||||||
|
if (validator is IValidator val)
|
||||||
|
{
|
||||||
|
reports.Clear();
|
||||||
|
reports.Add(val.Validate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type[] GetValidatorTypes()
|
||||||
|
{
|
||||||
|
return TypeCache.GetTypesDerivedFrom<IValidator>().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetWarningIconName(WarningType warningType)
|
||||||
|
{
|
||||||
|
return warningType switch
|
||||||
|
{
|
||||||
|
WarningType.Info => "d_console.warnicon.inactive.sml",
|
||||||
|
WarningType.Warning => "d_console.warnicon.sml",
|
||||||
|
WarningType.Error => "d_console.erroricon.sml",
|
||||||
|
_ => "d_console.erroricon.inactive.sml",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Editor/ValidatorEditorWindow.cs.meta
Normal file
11
Editor/ValidatorEditorWindow.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8f89d88b32f5b7c40a089dbec6b2c406
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Editor/Validators.meta
Normal file
8
Editor/Validators.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 69e4deb3492cc174aa67baedeefdb790
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
48
Editor/Validators/AssetValidator.cs
Normal file
48
Editor/Validators/AssetValidator.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Validator.Editor
|
||||||
|
{
|
||||||
|
public class AssetValidator : IValidator
|
||||||
|
{
|
||||||
|
public Report Validate()
|
||||||
|
{
|
||||||
|
Report reporter = new Report("AssetValidator");
|
||||||
|
|
||||||
|
List<Object> objects = FindAssetsByType<Object>();
|
||||||
|
for (int i = 0; i < objects.Count; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("AssetValidator", "Validate...", (float)i / objects.Count);
|
||||||
|
if (objects[i] is IValidatable validatable)
|
||||||
|
{
|
||||||
|
validatable.Validate(reporter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return reporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<T> FindAssetsByType<T>() where T : Object
|
||||||
|
{
|
||||||
|
List<T> assets = new List<T>();
|
||||||
|
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T)));
|
||||||
|
|
||||||
|
for (int i = 0; i < guids.Length; i++)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayProgressBar("AssetValidator", "FindAssetsByType...", (float)i / guids.Length);
|
||||||
|
|
||||||
|
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||||
|
T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath);
|
||||||
|
if (asset != null)
|
||||||
|
{
|
||||||
|
assets.Add(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
|
||||||
|
return assets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Editor/Validators/AssetValidator.cs.meta
Normal file
11
Editor/Validators/AssetValidator.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 458ef52fac9354e4fb723a3a8645dd2d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
55
Editor/Validators/SceneValidator.cs
Normal file
55
Editor/Validators/SceneValidator.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Editor/Validators/SceneValidator.cs.meta
Normal file
11
Editor/Validators/SceneValidator.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fced302525286954493f623662b36f33
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "COMPANYNAME.PACKAGENAME.Editor.Tests",
|
"name": "Validator.Editor",
|
||||||
|
"rootNamespace": "Validator.Editor",
|
||||||
"references": [
|
"references": [
|
||||||
"COMPANYNAME.PACKAGENAME",
|
"GUID:334c4fbff44e0f9439f29f9d8e0ce6e9"
|
||||||
"COMPANYNAME.PACKAGENAME.Editor"
|
|
||||||
],
|
],
|
||||||
"includePlatforms": [
|
"includePlatforms": [
|
||||||
"Editor"
|
"Editor"
|
||||||
@ -14,7 +14,5 @@
|
|||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": [],
|
"versionDefines": [],
|
||||||
"optionalUnityReferences": [
|
"noEngineReferences": false
|
||||||
"TestAssemblies"
|
|
||||||
]
|
|
||||||
}
|
}
|
7
Editor/VertexColor.Validator.Editor.asmdef.meta
Normal file
7
Editor/VertexColor.Validator.Editor.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 20d798ece823f744489d29f7453b3315
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 COMPANYNAME
|
Copyright (c) 2021 Max Kruf
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
7
LICENSE.md.meta
Normal file
7
LICENSE.md.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e466f8c2ce68a6a4eaa6a680cb28895b
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
30
README.md
30
README.md
@ -1,6 +1,32 @@
|
|||||||
# [COMPANYNAME]() - PACKAGENAME
|
# Validator
|
||||||
|
|
||||||
Description.
|
Unity project validator framework.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
Open Validator Window:
|
||||||
|
> Window -> General -> Validator
|
||||||
|
|
||||||
|
Add validatable:
|
||||||
|
```C#
|
||||||
|
using Validator;
|
||||||
|
|
||||||
|
public class MyBehaviour : MonoBehaviour, IValidatable
|
||||||
|
{
|
||||||
|
[SerializeField] private float startHealth = 10; // If someone was to put it to low <= 0, it would be invalid.
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
public void Validate(Report report)
|
||||||
|
{
|
||||||
|
// Check if health is valid.
|
||||||
|
if(startHealth <= 0)
|
||||||
|
{
|
||||||
|
// If not, log it.
|
||||||
|
report.Log(this, WarningType.Warning, ReportCategories.Design, $"{nameof(startHealth)} is to low", $"Make value > 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
7
README.md.meta
Normal file
7
README.md.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fe23a067c33426a459b6554df6d0487e
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Runtime.meta
Normal file
8
Runtime.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2752af9ac554eac43949290d597db9ab
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
9
Runtime/IValidatable.cs
Normal file
9
Runtime/IValidatable.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Validator
|
||||||
|
{
|
||||||
|
public interface IValidatable
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
public void Validate(Report report);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
11
Runtime/IValidatable.cs.meta
Normal file
11
Runtime/IValidatable.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9745876369d865247b2bae9393491734
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
60
Runtime/Report.cs
Normal file
60
Runtime/Report.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Validator
|
||||||
|
{
|
||||||
|
public enum WarningType
|
||||||
|
{
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Report
|
||||||
|
{
|
||||||
|
public struct ReportMessage
|
||||||
|
{
|
||||||
|
public Object Target => target;
|
||||||
|
public WarningType WarningType => warningType;
|
||||||
|
public string Category => category;
|
||||||
|
public string Message => message;
|
||||||
|
public string Solution => solution;
|
||||||
|
|
||||||
|
private readonly Object target;
|
||||||
|
private readonly WarningType warningType;
|
||||||
|
private readonly string category;
|
||||||
|
private readonly string message;
|
||||||
|
private readonly string solution;
|
||||||
|
|
||||||
|
public ReportMessage(Object target, WarningType warningLevel, string category, string message, string solution)
|
||||||
|
{
|
||||||
|
this.target = target;
|
||||||
|
this.warningType = warningLevel;
|
||||||
|
this.category = category;
|
||||||
|
this.message = message;
|
||||||
|
this.solution = solution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name => name;
|
||||||
|
|
||||||
|
public IList<ReportMessage> Reports => reports.AsReadOnly();
|
||||||
|
private readonly string name;
|
||||||
|
private readonly List<ReportMessage> reports = new List<ReportMessage>();
|
||||||
|
|
||||||
|
public Report(string name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(ReportMessage report)
|
||||||
|
{
|
||||||
|
reports.Add(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(Object target, WarningType warningType, string category, string message, string solution)
|
||||||
|
{
|
||||||
|
Log(new ReportMessage(target, warningType, category, message, solution));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Runtime/Report.cs.meta
Normal file
11
Runtime/Report.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d39518e0aab78db47adc586ce678d8a9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
9
Runtime/ReportCategories.cs
Normal file
9
Runtime/ReportCategories.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace Validator
|
||||||
|
{
|
||||||
|
public static partial class ReportCategories
|
||||||
|
{
|
||||||
|
public const string Art = "Art";
|
||||||
|
public const string Design = "Design";
|
||||||
|
public const string Code = "Code";
|
||||||
|
}
|
||||||
|
}
|
11
Runtime/ReportCategories.cs.meta
Normal file
11
Runtime/ReportCategories.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d2016a6a28d54304ea9cd64801c4f0b9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,5 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace COMPANYNAME.PACKAGENAME
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "COMPANYNAME.PACKAGENAME",
|
"name": "VertexColor.Validator",
|
||||||
|
"rootNamespace": "Validator",
|
||||||
"references": [],
|
"references": [],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
@ -8,5 +9,6 @@
|
|||||||
"precompiledReferences": [],
|
"precompiledReferences": [],
|
||||||
"autoReferenced": true,
|
"autoReferenced": true,
|
||||||
"defineConstraints": [],
|
"defineConstraints": [],
|
||||||
"versionDefines": []
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
}
|
}
|
7
Runtime/VertexColor.Validator.asmdef.meta
Normal file
7
Runtime/VertexColor.Validator.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 334c4fbff44e0f9439f29f9d8e0ce6e9
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,2 +0,0 @@
|
|||||||
This is just a template package with a template sample folder structure.
|
|
||||||
Import of this example file is successful!
|
|
7
THIRD PARTY NOTICES.md.meta
Normal file
7
THIRD PARTY NOTICES.md.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e3e716ef6981e984eb7f8a0196a2dc92
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,26 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEngine.TestTools;
|
|
||||||
using UnityEditor;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
namespace COMPANYNAME.PACKAGENAME.Editor.Tests
|
|
||||||
{
|
|
||||||
public class TestEditorExample
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestEditorExampleSimplePasses()
|
|
||||||
{
|
|
||||||
// Use the Assert class to test conditions
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnityTest]
|
|
||||||
public IEnumerator TestEditorExampleWithEnumeratorPasses()
|
|
||||||
{
|
|
||||||
// Use the Assert class to test conditions.
|
|
||||||
// Use yield to skip a frame.
|
|
||||||
yield return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "COMPANYNAME.PACKAGENAME.Tests",
|
|
||||||
"references": [
|
|
||||||
"COMPANYNAME.PACKAGENAME"
|
|
||||||
],
|
|
||||||
"includePlatforms": [],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": false,
|
|
||||||
"overrideReferences": false,
|
|
||||||
"precompiledReferences": [],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [],
|
|
||||||
"versionDefines": [],
|
|
||||||
"optionalUnityReferences": [
|
|
||||||
"TestAssemblies"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEngine.TestTools;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
namespace COMPANYNAME.PACKAGENAME.Tests
|
|
||||||
{
|
|
||||||
public class TestRuntimeExample
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestRuntimeExampleSimplePasses()
|
|
||||||
{
|
|
||||||
// Use the Assert class to test conditions
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnityTest]
|
|
||||||
public IEnumerator TestRuntimeExampleEnumeratorPasses()
|
|
||||||
{
|
|
||||||
// Use the Assert class to test conditions.
|
|
||||||
// Use yield to skip a frame.
|
|
||||||
yield return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
20
package.json
20
package.json
@ -1,10 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "com.COMPANYNAME.PACKAGENAME",
|
"name": "com.vertexcolor.validator",
|
||||||
"displayName": "Template Unity Package",
|
"displayName": "Validator",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"unity": "2019.3",
|
"unity": "2019.3",
|
||||||
"unityRelease": "7f1",
|
"description": "Unity project validator framework.",
|
||||||
"description": "This is a template package, used as a basis to build a bigger one.",
|
|
||||||
"category": "Tool",
|
"category": "Tool",
|
||||||
"type": "tool",
|
"type": "tool",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -13,18 +12,7 @@
|
|||||||
"email": "info@maxartz15.com",
|
"email": "info@maxartz15.com",
|
||||||
"url": "https://www.maxartz15.com"
|
"url": "https://www.maxartz15.com"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
|
||||||
"com.maxartz15.package1": "0.1.0"
|
|
||||||
},
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"COMPANYNAME",
|
"Validator"
|
||||||
"PACKAGENAME"
|
|
||||||
],
|
|
||||||
"samples": [
|
|
||||||
{
|
|
||||||
"displayName": "Example 1",
|
|
||||||
"description": "This sample is just an example",
|
|
||||||
"path": "Samples~/Example1"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
7
package.json.meta
Normal file
7
package.json.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 84601f755fc0e304f85a3ebf67e1601b
|
||||||
|
PackageManifestImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user