Added GameObject Validators
This commit is contained in:
parent
c8a6815316
commit
269789b36f
15 changed files with 160 additions and 13 deletions
|
|
@ -10,6 +10,7 @@ namespace Module.ProjectValidator.Editor
|
|||
{
|
||||
private readonly Dictionary<Type, object> _attributeValidators = new();
|
||||
private readonly Dictionary<Type, List<object>> _componentValidators = new();
|
||||
public readonly List<IGameObjectValidator> GameObjectValidators = new();
|
||||
|
||||
public void AddAttribute(Type type)
|
||||
{
|
||||
|
|
@ -59,6 +60,22 @@ namespace Module.ProjectValidator.Editor
|
|||
}
|
||||
}
|
||||
|
||||
public void AddGameObject(Type type)
|
||||
{
|
||||
if (type.IsInterface || type.IsAbstract)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var instance = (IGameObjectValidator)FormatterServices.GetUninitializedObject(type);
|
||||
GameObjectValidators.Add(instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetAttributeValidator(Type type, out object validatorInstance)
|
||||
{
|
||||
return _attributeValidators.TryGetValue(type, out validatorInstance);
|
||||
|
|
|
|||
|
|
@ -38,14 +38,14 @@ namespace Module.ProjectValidator.Editor
|
|||
return window;
|
||||
}
|
||||
|
||||
internal static string GetAttributeShortName(Attribute attribute)
|
||||
internal static string GetGameObjectValidatorName(IGameObjectValidator validator)
|
||||
{
|
||||
var str = attribute.GetType().Name;
|
||||
str = str.Replace("Attribute", string.Empty);
|
||||
var str = validator.GetType().Name;
|
||||
str = str.Replace("GameObjectValidator", string.Empty);
|
||||
str = ObjectNames.NicifyVariableName(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
internal static string GetComponentValidatorShortName(object obj)
|
||||
{
|
||||
var str = obj.GetType().Name;
|
||||
|
|
@ -53,7 +53,15 @@ namespace Module.ProjectValidator.Editor
|
|||
str = ObjectNames.NicifyVariableName(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
internal static string GetAttributeShortName(Attribute attribute)
|
||||
{
|
||||
var str = attribute.GetType().Name;
|
||||
str = str.Replace("Attribute", string.Empty);
|
||||
str = ObjectNames.NicifyVariableName(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
internal static void AppendToScenePath(GameObject gameObject, ref string scenePath)
|
||||
{
|
||||
scenePath = string.IsNullOrEmpty(scenePath) ? gameObject.name : $"{scenePath}/{gameObject.name}";
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace Module.ProjectValidator.Editor
|
|||
ProjectValidatorUtility.OpenWindow();
|
||||
|
||||
stopwatch.Stop();
|
||||
Debug.Log(stopwatch.Elapsed.TotalMilliseconds + "ms");
|
||||
Debug.Log($"Validator took {stopwatch.Elapsed.TotalMilliseconds}ms");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -63,9 +63,10 @@ namespace Module.ProjectValidator.Editor
|
|||
|
||||
_validatorList = new ValidatorList();
|
||||
_typeTree = new TypeTree();
|
||||
|
||||
FetchAllAttributeValidators();
|
||||
|
||||
FetchAllGameObjectValidators();
|
||||
FetchAllComponentValidators();
|
||||
FetchAllAttributeValidators();
|
||||
FetchAllTypesWithValidators<Component>(assemblies);
|
||||
FetchAllTypesWithValidators<ScriptableObject>(assemblies);
|
||||
_initialized = true;
|
||||
|
|
@ -100,6 +101,16 @@ namespace Module.ProjectValidator.Editor
|
|||
_validatorList.AddAttribute(types[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void FetchAllGameObjectValidators()
|
||||
{
|
||||
var types = TypeCache.GetTypesDerivedFrom(typeof(IGameObjectValidator));
|
||||
|
||||
for (var i = 0; i < types.Count; i++)
|
||||
{
|
||||
_validatorList.AddGameObject(types[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void FetchAllComponentValidators()
|
||||
{
|
||||
|
|
@ -188,19 +199,39 @@ namespace Module.ProjectValidator.Editor
|
|||
private static void ValidateGameObject(GameObject gameObject, string scenePath, Report report)
|
||||
{
|
||||
ProjectValidatorUtility.AppendToScenePath(gameObject, ref scenePath);
|
||||
ValidateComponents(gameObject, scenePath, report);
|
||||
|
||||
var assetGuid = EditorAssetUtility.GetAssetGuid(gameObject);
|
||||
using var _ = ListPool<ValidatorResult>.Get(out var results);
|
||||
|
||||
for (var i = 0; i < _validatorList.GameObjectValidators.Count; i++)
|
||||
{
|
||||
results.Clear();
|
||||
|
||||
_validatorList.GameObjectValidators[i].Validate(gameObject, results);
|
||||
var type = ProjectValidatorUtility.GetGameObjectValidatorName(_validatorList.GameObjectValidators[i]);
|
||||
|
||||
for (var j = 0; j < results.Count; j++)
|
||||
{
|
||||
var result = results[j];
|
||||
|
||||
if (result.Severity != EValidatorSeverity.Valid)
|
||||
report.Add(assetGuid, scenePath, string.Empty, type, result.Severity, result.Message);
|
||||
}
|
||||
}
|
||||
|
||||
ValidateComponents(gameObject, assetGuid, scenePath, report);
|
||||
ValidateChildren(gameObject, scenePath, report);
|
||||
}
|
||||
|
||||
private static void ValidateComponents(GameObject gameObject, string scenePath, Report report)
|
||||
private static void ValidateComponents(GameObject gameObject, GUID assetGuid, string scenePath, Report report)
|
||||
{
|
||||
using var _ = ListPool<Component>.Get(out var components);
|
||||
var assetGuid = EditorAssetUtility.GetAssetGuid(gameObject);
|
||||
gameObject.GetComponents(components);
|
||||
|
||||
for (var i = 0; i < components.Count; i++)
|
||||
{
|
||||
Validate(assetGuid, scenePath, components[i], report);
|
||||
if (components[i] != null)
|
||||
Validate(assetGuid, scenePath, components[i], report);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Module.ProjectValidator.Editor
|
||||
{
|
||||
internal sealed class ComponentValidatorSkinnedMeshRenderer : IComponentValidator<SkinnedMeshRenderer>
|
||||
{
|
||||
public void Validate(SkinnedMeshRenderer component, List<ValidatorResult> results)
|
||||
{
|
||||
var materials = component.sharedMaterials;
|
||||
|
||||
for (var i = 0; i < materials.Length; i++)
|
||||
{
|
||||
if (materials[i] == null)
|
||||
results.Add(ValidatorResult.Create(EValidatorSeverity.Error, $"Missing material in slot #{i}"));
|
||||
}
|
||||
|
||||
if (component.sharedMesh == null)
|
||||
results.Add(ValidatorResult.Create(EValidatorSeverity.Error, "Missing mesh"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1610561c53a0aa84aaa903e5dde29694
|
||||
3
Editor/Validators/GameObject.meta
Normal file
3
Editor/Validators/GameObject.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 45fa253dcfa349d5b1e9bd56ebac7c98
|
||||
timeCreated: 1779133809
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Module.ProjectValidator.Editor
|
||||
{
|
||||
internal sealed class GameObjectValidatorBrokenPrefab : IGameObjectValidator
|
||||
{
|
||||
public void Validate(GameObject gameObject, List<ValidatorResult> results)
|
||||
{
|
||||
if (PrefabUtility.IsPrefabAssetMissing(gameObject))
|
||||
results.Add(ValidatorResult.Create(EValidatorSeverity.Error, "GameObject is missing prefab asset"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8fd1dfcd3d564622a918e2175499318d
|
||||
timeCreated: 1779133864
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Module.ProjectValidator.Editor
|
||||
{
|
||||
internal sealed class GameObjectValidatorMissingComponents : IGameObjectValidator
|
||||
{
|
||||
public void Validate(GameObject gameObject, List<ValidatorResult> results)
|
||||
{
|
||||
var count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(gameObject);
|
||||
|
||||
if (count != 0)
|
||||
results.Add(ValidatorResult.Create(EValidatorSeverity.Error, $"GameObject is missing {count} component(s)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 66cbc43729ec4e81a9e353e537b3ccf0
|
||||
timeCreated: 1779133947
|
||||
13
README.md
13
README.md
|
|
@ -9,6 +9,19 @@ A tool to help validate data across scenes, prefabs and scriptable objects.
|
|||

|
||||

|
||||
|
||||
## Game Object Validators
|
||||
|
||||
```csharp
|
||||
public sealed class GameObjectValidatorBrokenPrefab : IGameObjectValidator
|
||||
{
|
||||
public void Validate(GameObject gameObject, List<ValidatorResult> results)
|
||||
{
|
||||
if (PrefabUtility.IsPrefabAssetMissing(gameObject))
|
||||
results.Add(ValidatorResult.Create(EValidatorSeverity.Error, "GameObject is missing prefab asset"));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Component Validators
|
||||
|
||||
```csharp
|
||||
|
|
|
|||
10
Runtime/Interfaces/IGameObjectValidator.cs
Normal file
10
Runtime/Interfaces/IGameObjectValidator.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Module.ProjectValidator
|
||||
{
|
||||
public interface IGameObjectValidator
|
||||
{
|
||||
void Validate(GameObject gameObject, List<ValidatorResult> results);
|
||||
}
|
||||
}
|
||||
3
Runtime/Interfaces/IGameObjectValidator.cs.meta
Normal file
3
Runtime/Interfaces/IGameObjectValidator.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f7513a02611842029edd675cb64989ad
|
||||
timeCreated: 1779133097
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "com.module.project-validator",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"displayName": "Module.ProjectValidator",
|
||||
"description": "",
|
||||
"unity": "6000.3",
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 154 KiB |
Loading…
Add table
Add a link
Reference in a new issue