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:
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- Start Project:
|
||||
- ...
|
||||
- Base validator framework.
|
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.
|
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": [
|
||||
"COMPANYNAME.PACKAGENAME",
|
||||
"COMPANYNAME.PACKAGENAME.Editor"
|
||||
"GUID:334c4fbff44e0f9439f29f9d8e0ce6e9"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
@ -14,7 +14,5 @@
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
]
|
||||
"noEngineReferences": false
|
||||
}
|
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
|
||||
|
||||
Copyright (c) 2021 COMPANYNAME
|
||||
Copyright (c) 2021 Max Kruf
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
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
|
||||
|
||||
|
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": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
@ -8,5 +9,6 @@
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"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",
|
||||
"displayName": "Template Unity Package",
|
||||
"name": "com.vertexcolor.validator",
|
||||
"displayName": "Validator",
|
||||
"version": "0.1.0",
|
||||
"unity": "2019.3",
|
||||
"unityRelease": "7f1",
|
||||
"description": "This is a template package, used as a basis to build a bigger one.",
|
||||
"description": "Unity project validator framework.",
|
||||
"category": "Tool",
|
||||
"type": "tool",
|
||||
"license": "MIT",
|
||||
@ -13,18 +12,7 @@
|
||||
"email": "info@maxartz15.com",
|
||||
"url": "https://www.maxartz15.com"
|
||||
},
|
||||
"dependencies": {
|
||||
"com.maxartz15.package1": "0.1.0"
|
||||
},
|
||||
"keywords": [
|
||||
"COMPANYNAME",
|
||||
"PACKAGENAME"
|
||||
],
|
||||
"samples": [
|
||||
{
|
||||
"displayName": "Example 1",
|
||||
"description": "This sample is just an example",
|
||||
"path": "Samples~/Example1"
|
||||
}
|
||||
"Validator"
|
||||
]
|
||||
}
|
||||
|
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