diff --git a/Editor/Hierarchy/EditorProjectValidatorHierarchy.cs b/Editor/Hierarchy/EditorProjectValidatorHierarchy.cs index cacd52c..a41dbc3 100644 --- a/Editor/Hierarchy/EditorProjectValidatorHierarchy.cs +++ b/Editor/Hierarchy/EditorProjectValidatorHierarchy.cs @@ -10,32 +10,19 @@ namespace Module.ProjectValidator.Editor { static EditorProjectValidatorHierarchy() { -#if UNITY_6000_4_OR_NEWER - EditorApplication.hierarchyWindowItemByEntityIdOnGUI -= OnHierarchyWindowItemByEntityIdOnGUI; - EditorApplication.hierarchyWindowItemByEntityIdOnGUI += OnHierarchyWindowItemByEntityIdOnGUI; -#else EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyWindowItemOnGUI; EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemOnGUI; -#endif EditorSceneManager.sceneOpened -= OnSceneOpened; EditorSceneManager.sceneOpened += OnSceneOpened; } -#if UNITY_6000_4_OR_NEWER - private static void OnHierarchyWindowItemByEntityIdOnGUI(EntityId entityId, Rect selectionRect) - { - if (Report.HasActive && Report.Active.TryGetSeverityFor(entityId, out var instance) && instance.Severity != EValidatorSeverity.Valid) - EditorIconUtility.Draw(new Rect(selectionRect.x, selectionRect.y, selectionRect.height, selectionRect.height), instance.Severity, instance.IsRedirect); - } -#else private static void OnHierarchyWindowItemOnGUI(int instanceID, Rect selectionRect) { if (Report.HasActive && Report.Active.TryGetSeverityFor(instanceID, out var instance) && instance.Severity != EValidatorSeverity.Valid) EditorIconUtility.Draw(new Rect(selectionRect.x, selectionRect.y, selectionRect.height, selectionRect.height), instance.Severity, instance.IsRedirect); } -#endif - + private static void OnSceneOpened(Scene scene, OpenSceneMode mode) { if (Report.HasActive && ProjectValidatorUtility.IsValidForRun()) diff --git a/Editor/Icons/editor_project_validator_settings.png b/Editor/Icons/editor_project_validator_settings.png deleted file mode 100644 index f938577..0000000 Binary files a/Editor/Icons/editor_project_validator_settings.png and /dev/null differ diff --git a/Editor/Icons/editor_project_validator_settings.png.meta b/Editor/Icons/editor_project_validator_settings.png.meta deleted file mode 100644 index 524687d..0000000 --- a/Editor/Icons/editor_project_validator_settings.png.meta +++ /dev/null @@ -1,117 +0,0 @@ -fileFormatVersion: 2 -guid: a6c61d5fbd310894d8159ba6af32d7e3 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 13 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - flipGreenChannel: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - vTOnly: 0 - ignoreMipmapLimit: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 1 - mipBias: 0 - wrapU: 0 - wrapV: 0 - wrapW: 0 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 1 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - swizzle: 50462976 - cookieLightType: 0 - platformSettings: - - serializedVersion: 4 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 4 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - customData: - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spriteCustomMetadata: - entries: [] - nameFileIdTable: {} - mipmapLimitGroupName: - pSDRemoveMatte: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Editor/Objects/Report.cs b/Editor/Objects/Report.cs index 5b68f9f..aa6d136 100644 --- a/Editor/Objects/Report.cs +++ b/Editor/Objects/Report.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using UnityEditor; -using UnityEngine; namespace Module.ProjectValidator.Editor { @@ -12,12 +11,7 @@ namespace Module.ProjectValidator.Editor public readonly List Entries = new(); private readonly Dictionary _assetToSeverityMapping = new(); - -#if UNITY_6000_4_OR_NEWER - private readonly Dictionary _instanceToSeverityMapping = new(); -#else private readonly Dictionary _instanceToSeverityMapping = new(); -#endif public void Add(GUID assetGuid, string relativePath, string fieldPath, Attribute attribute, EValidatorSeverity severity, string message) { @@ -70,17 +64,7 @@ namespace Module.ProjectValidator.Editor mapping = new MappingEntry(); return false; } - -#if UNITY_6000_4_OR_NEWER - public bool TryGetSeverityFor(EntityId entityId, out MappingEntry mapping) - { - if (_instanceToSeverityMapping.TryGetValue(entityId, out mapping)) - return true; - - mapping = new MappingEntry(); - return false; - } -#else + public bool TryGetSeverityFor(int instanceId, out MappingEntry mapping) { if (_instanceToSeverityMapping.TryGetValue(instanceId, out mapping)) @@ -89,7 +73,6 @@ namespace Module.ProjectValidator.Editor mapping = new MappingEntry(); return false; } -#endif public bool TryGetSeverityFor(GUID assetGuid, string relativePath, out MappingEntry mapping) { diff --git a/Editor/Objects/TypeTree.cs b/Editor/Objects/TypeTree.cs index 4cddc30..5b69e0c 100644 --- a/Editor/Objects/TypeTree.cs +++ b/Editor/Objects/TypeTree.cs @@ -31,16 +31,9 @@ namespace Module.ProjectValidator.Editor if (!IsFieldSerializable(fi)) continue; - var fieldAttributes = fi.GetCustomAttributes(); - var fieldTypeAttributes = fi.FieldType.GetCustomAttributes(); + var attributes = fi.GetCustomAttributes(); - foreach (var attribute in fieldAttributes) - { - if (validatorList.TryGetAttributeValidator(attribute.GetType(), out var validator)) - entry.AddField(fi, attribute, validator); - } - - foreach (var attribute in fieldTypeAttributes) + foreach (var attribute in attributes) { if (validatorList.TryGetAttributeValidator(attribute.GetType(), out var validator)) entry.AddField(fi, attribute, validator); @@ -171,7 +164,7 @@ namespace Module.ProjectValidator.Editor return Components == null && Fields == null && Entries == null; } } - + public sealed class ValidatorField { public readonly FieldInfo FieldInfo; diff --git a/Editor/Objects/ValidatorList.cs b/Editor/Objects/ValidatorList.cs index 39221ff..0f498fa 100644 --- a/Editor/Objects/ValidatorList.cs +++ b/Editor/Objects/ValidatorList.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Runtime.Serialization; using UnityEngine; @@ -12,7 +11,6 @@ namespace Module.ProjectValidator.Editor private readonly Dictionary _attributeValidators = new(); private readonly Dictionary> _componentValidators = new(); public readonly List GameObjectValidators = new(); - public readonly Dictionary> AssetValidators = new(); public void AddAttribute(Type type) { @@ -77,33 +75,6 @@ namespace Module.ProjectValidator.Editor Debug.LogException(e); } } - - public void AddAsset(Type type) - { - if (type.IsInterface || type.IsAbstract) - return; - - var typeValidator = type.GetInterfaces().FirstOrDefault(typeInterface => typeInterface.IsGenericType && typeInterface.GetGenericTypeDefinition() == typeof(IAssetValidator<>)); - var componentType = typeValidator?.GetGenericArguments()[0]; - - if (componentType == null) - return; - - try - { - var instance = FormatterServices.GetUninitializedObject(type); - var validator = new AssetValidator(instance); - - if (AssetValidators.TryGetValue(componentType, out var list)) - list.Add(validator); - else - AssetValidators.Add(componentType, new List { validator }); - } - catch (Exception e) - { - Debug.LogException(e); - } - } public bool TryGetAttributeValidator(Type type, out object validatorInstance) { @@ -114,17 +85,5 @@ namespace Module.ProjectValidator.Editor { return _componentValidators.TryGetValue(type, out validatorInstances); } - - public sealed class AssetValidator - { - public readonly object Validator; - public readonly MethodInfo ValidatorMethod; - - public AssetValidator(object validator) - { - Validator = validator; - ValidatorMethod = validator.GetType().GetMethod("Validate"); - } - } } } \ No newline at end of file diff --git a/Editor/Settings/ProjectValidatorSettings.cs b/Editor/Settings/ProjectValidatorSettings.cs index ec2893f..b526db7 100644 --- a/Editor/Settings/ProjectValidatorSettings.cs +++ b/Editor/Settings/ProjectValidatorSettings.cs @@ -1,36 +1,27 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; using UnityEditor.UIElements; using UnityEditorInternal; -using UnityEngine.Pool; -using Object = UnityEngine.Object; namespace Module.ProjectValidator.Editor { internal sealed class ProjectValidatorSettings : ScriptableObject { public List assemblies = new(); - [NonReorderable] - public List validators = new(); - - public const string MenuPath = "Project/Project Validator"; + private const string AssetPath = "ProjectSettings/ProjectValidatorSettings.asset"; private const string StyleSheetName = "StyleSheetProjectValidatorSettings"; internal static ProjectValidatorSettings GetOrCreate() { var objects = InternalEditorUtility.LoadSerializedFileAndForget(AssetPath); - ProjectValidatorSettings settings; if (objects.Length != 0) - settings = (ProjectValidatorSettings)objects[0]; - else - settings = CreateInstance(); + return (ProjectValidatorSettings)objects[0]; - PopulateValidatorList(settings); + var settings = CreateInstance(); InternalEditorUtility.SaveToSerializedFileAndForget(new Object[] { settings }, AssetPath, true); return settings; } @@ -38,7 +29,7 @@ namespace Module.ProjectValidator.Editor [SettingsProvider] public static SettingsProvider CreateProvider() { - return new SettingsProvider(MenuPath, SettingsScope.Project) + return new SettingsProvider("Project/Project Validator", SettingsScope.Project) { label = "Project Validator", activateHandler = (_, root) => @@ -46,79 +37,16 @@ namespace Module.ProjectValidator.Editor var settings = GetOrCreate(); var serializedObject = new SerializedObject(settings); var container = new VisualElement { style = { flexDirection = FlexDirection.Column } }; - - var assemblyField = new PropertyField(serializedObject.FindProperty(nameof(assemblies)), "Assemblies"); - container.Add(assemblyField); - - var enabledField = new PropertyField(serializedObject.FindProperty(nameof(validators)), "Validators"); - container.Add(enabledField); - + var propertyField = new PropertyField(serializedObject.FindProperty("assemblies"), "Assemblies"); + propertyField.RegisterCallback>(_ => InternalEditorUtility.SaveToSerializedFileAndForget(new[] { serializedObject.targetObject }, AssetPath, true)); + propertyField.RegisterValueChangeCallback(_ => InternalEditorUtility.SaveToSerializedFileAndForget(new[] { serializedObject.targetObject }, AssetPath, true)); + container.Add(propertyField); root.Add(container); root.Bind(serializedObject); - root.RegisterCallback(_ => InternalEditorUtility.SaveToSerializedFileAndForget(new[] { serializedObject.targetObject }, AssetPath, true)); - root.RegisterCallback(_ => InternalEditorUtility.SaveToSerializedFileAndForget(new[] { serializedObject.targetObject }, AssetPath, true)); root.styleSheets.Add(EditorAssetUtility.LoadFirstAsset(StyleSheetName)); }, keywords = new HashSet(new[] { "Project", "Validator", "Assemblies" }) }; } - - private static void PopulateValidatorList(ProjectValidatorSettings settings) - { - using var pool0 = ListPool.Get(out var list); - using var pool1 = ListPool.Get(out var temp); - - FetchValidatorsOfType(typeof(IAssetValidator<>), list); - FetchValidatorsOfType(typeof(IAttributeValidator<>), list); - FetchValidatorsOfType(typeof(IComponentValidator<>), list); - FetchValidatorsOfType(typeof(IGameObjectValidator), list); - - for (var i = 0; i < settings.validators.Count; i++) - { - temp.Add(settings.validators[i].assemblyQualifiedName); - } - - for (var i = 0; i < list.Count; i++) - { - if (temp.Contains(list[i])) - continue; - - var type = Type.GetType(list[i]); - var name = type != null ? type.Name : "Unknown Type"; - settings.validators.Add(new ValidatorEnabled(name, list[i], true)); - } - - for (var i = temp.Count - 1; i >= 0; i--) - { - if (!list.Contains(temp[i])) - settings.validators.RemoveAt(i); - } - } - - private static void FetchValidatorsOfType(Type type, List typeNames) - { - var types = TypeCache.GetTypesDerivedFrom(type); - - for (var i = 0; i < types.Count; i++) - { - if (!types[i].IsInterface && !types[i].IsAbstract) - typeNames.Add(types[i].AssemblyQualifiedName); - } - } - - [Serializable] - public sealed class ValidatorEnabled - { - public string name; - public string assemblyQualifiedName; - public bool enabled; - - public ValidatorEnabled(string name, string assemblyQualifiedName, bool enabled) - { - this.name = name; - this.assemblyQualifiedName = assemblyQualifiedName; - this.enabled = enabled; - } - } } } \ No newline at end of file diff --git a/Editor/Utilities/EditorAssetUtility.cs b/Editor/Utilities/EditorAssetUtility.cs index e3c0ea4..be7796a 100644 --- a/Editor/Utilities/EditorAssetUtility.cs +++ b/Editor/Utilities/EditorAssetUtility.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; -using Object = UnityEngine.Object; namespace Module.ProjectValidator.Editor { @@ -31,22 +29,6 @@ namespace Module.ProjectValidator.Editor return list.ToArray(); } - public static Object[] LoadAllAssets(Type type) - { - var guids = AssetDatabase.FindAssetGUIDs($"a:assets t:{type.Name}"); - var list = new List(guids.Length); - - foreach (var guid in guids) - { - var asset = AssetDatabase.LoadAssetByGUID(guid, type); - - if (asset != null) - list.Add(asset); - } - - return list.ToArray(); - } - internal static GUID GetAssetGuid(Object obj) { var assetPath = string.Empty; diff --git a/Editor/Utilities/ProjectValidatorUtility.cs b/Editor/Utilities/ProjectValidatorUtility.cs index 10d6eef..f9f520c 100644 --- a/Editor/Utilities/ProjectValidatorUtility.cs +++ b/Editor/Utilities/ProjectValidatorUtility.cs @@ -37,14 +37,6 @@ namespace Module.ProjectValidator.Editor window.titleContent = new GUIContent("Project Validator"); return window; } - - public static string GetAssetValidatorName(object validator) - { - var str = validator.GetType().Name; - str = str.Replace("AssetValidator", string.Empty); - str = ObjectNames.NicifyVariableName(str); - return str; - } internal static string GetGameObjectValidatorName(IGameObjectValidator validator) { @@ -204,93 +196,6 @@ namespace Module.ProjectValidator.Editor } } -#if UNITY_6000_4_OR_NEWER - internal static void RebuildSceneInstanceMapping(Report report, Dictionary dictMapping) - { - dictMapping.Clear(); - using var _ = ListPool.Get(out var rootObjects); - - for (var i = 0; i < SceneManager.sceneCount; i++) - { - var scene = SceneManager.GetSceneAt(i); - - if (!scene.isLoaded) - continue; - - var strAssetGuid = AssetDatabase.AssetPathToGUID(scene.path); - GUID.TryParse(strAssetGuid, out var assetGuid); - scene.GetRootGameObjects(rootObjects); - - for (var j = 0; j < rootObjects.Count; j++) - { - var rootObject = rootObjects[j]; - var relativePath = string.Empty; - RebuildSceneInstanceMapping(report, dictMapping, rootObject, assetGuid, relativePath, true); - } - } - - RebuildForAllParents(dictMapping); - } - - - private static void RebuildSceneInstanceMapping(Report report, Dictionary dictMapping, GameObject gameObject, GUID assetGuid, string relativePath, bool initial) - { - var transform = gameObject.transform; - AppendToRelativePath(gameObject, ref relativePath, initial); - - if (report.TryGetSeverityFor(assetGuid, relativePath, out var mapping)) - dictMapping.Add(gameObject.GetEntityId(), new Report.MappingEntry(mapping.Severity, false)); - - for (var i = 0; i < transform.childCount; i++) - { - RebuildSceneInstanceMapping(report, dictMapping, transform.GetChild(i).gameObject, assetGuid, relativePath, false); - } - } - - private static void RebuildForAllParents(Dictionary dictMapping) - { - using var _ = DictionaryPool.Get(out var newMappings); - - foreach (var pair in dictMapping) - { - var obj = EditorUtility.EntityIdToObject(pair.Key); - - if (obj is not GameObject gameObject) - continue; - - var severity = pair.Value.Severity; - var transform = gameObject.transform.parent; - - while (transform != null) - { - gameObject = transform.gameObject; - var entityId = gameObject.GetEntityId(); - - if (dictMapping.TryGetValue(entityId, out var parentMapping)) - { - if (severity < parentMapping.Severity) - severity = parentMapping.Severity; - } - else if (newMappings.TryGetValue(entityId, out var currentMapping)) - { - if (currentMapping.Severity < severity) - newMappings[entityId] = new Report.MappingEntry(severity, true); - } - else - { - newMappings.Add(entityId, new Report.MappingEntry(severity, true)); - } - - transform = transform.parent; - } - } - - foreach (var pair in newMappings) - { - dictMapping.Add(pair.Key, pair.Value); - } - } -#else internal static void RebuildSceneInstanceMapping(Report report, Dictionary dictMapping) { dictMapping.Clear(); @@ -318,7 +223,6 @@ namespace Module.ProjectValidator.Editor RebuildForAllParents(dictMapping); } - private static void RebuildSceneInstanceMapping(Report report, Dictionary dictMapping, GameObject gameObject, GUID assetGuid, string relativePath, bool initial) { var transform = gameObject.transform; @@ -376,7 +280,6 @@ namespace Module.ProjectValidator.Editor dictMapping.Add(pair.Key, pair.Value); } } -#endif internal static void RefreshUnityWindows() { diff --git a/Editor/ValidatorRunner.cs b/Editor/ValidatorRunner.cs index b69797a..3cbfa63 100644 --- a/Editor/ValidatorRunner.cs +++ b/Editor/ValidatorRunner.cs @@ -13,6 +13,7 @@ namespace Module.ProjectValidator.Editor { internal static class ValidatorRunner { + private static bool _initialized; private static ValidatorList _validatorList; private static TypeTree _typeTree; @@ -55,19 +56,21 @@ namespace Module.ProjectValidator.Editor private static void Initialize() { + if (_initialized) + return; + var settings = ProjectValidatorSettings.GetOrCreate(); var assemblies = GetAssembliesFrom(settings); - var enabled = GetEnabledValidators(settings); - + _validatorList = new ValidatorList(); _typeTree = new TypeTree(); - FetchAllGameObjectValidators(enabled); - FetchAllComponentValidators(enabled); - FetchAllAttributeValidators(enabled); - FetchAllAssetValidators(enabled); + FetchAllGameObjectValidators(); + FetchAllComponentValidators(); + FetchAllAttributeValidators(); FetchAllTypesWithValidators(assemblies); FetchAllTypesWithValidators(assemblies); + _initialized = true; } private static Assembly[] GetAssembliesFrom(ProjectValidatorSettings settings) @@ -90,72 +93,33 @@ namespace Module.ProjectValidator.Editor return assemblies.ToArray(); } - private static HashSet GetEnabledValidators(ProjectValidatorSettings settings) - { - var enabled = new HashSet(settings.validators.Count); - - for (var i = 0; i < settings.validators.Count; i++) - { - try - { - if (!settings.validators[i].enabled) - continue; - - var type = Type.GetType(settings.validators[i].assemblyQualifiedName); - - if (type != null) - enabled.Add(type); - } - catch (Exception e) - { - Debug.LogException(e); - } - } - - return enabled; - } - - private static void FetchAllAttributeValidators(HashSet enabled) + private static void FetchAllAttributeValidators() { var types = TypeCache.GetTypesDerivedFrom(typeof(IAttributeValidator<>)); for (var i = 0; i < types.Count; i++) { - if (enabled.Contains(types[i])) - _validatorList.AddAttribute(types[i]); + _validatorList.AddAttribute(types[i]); } } - private static void FetchAllGameObjectValidators(HashSet enabled) + private static void FetchAllGameObjectValidators() { var types = TypeCache.GetTypesDerivedFrom(typeof(IGameObjectValidator)); for (var i = 0; i < types.Count; i++) { - if (enabled.Contains(types[i])) - _validatorList.AddGameObject(types[i]); + _validatorList.AddGameObject(types[i]); } } - private static void FetchAllComponentValidators(HashSet enabled) + private static void FetchAllComponentValidators() { var types = TypeCache.GetTypesDerivedFrom(typeof(IComponentValidator<>)); for (var i = 0; i < types.Count; i++) { - if (enabled.Contains(types[i])) - _validatorList.AddComponent(types[i]); - } - } - - private static void FetchAllAssetValidators(HashSet enabled) - { - var types = TypeCache.GetTypesDerivedFrom(typeof(IAssetValidator<>)); - - for (var i = 0; i < types.Count; i++) - { - if (enabled.Contains(types[i])) - _validatorList.AddAsset(types[i]); + _validatorList.AddComponent(types[i]); } } @@ -179,12 +143,12 @@ namespace Module.ProjectValidator.Editor for (var i = 0; i < assets.Length; i++) { - var assetPath = AssetDatabase.GetAssetPath(assets[i]); - var scene = SceneManager.GetSceneByPath(assetPath); - var isLoaded = scene.isLoaded; - try { + var assetPath = AssetDatabase.GetAssetPath(assets[i]); + var scene = SceneManager.GetSceneByPath(assetPath); + var isLoaded = scene.isLoaded; + if (!isLoaded) scene = EditorSceneManager.OpenScene(assetPath, OpenSceneMode.Additive); @@ -194,41 +158,20 @@ namespace Module.ProjectValidator.Editor { ValidateGameObject(rootObjects[j], string.Empty, report, true); } + + if (!isLoaded) + EditorSceneManager.CloseScene(scene, true); } catch (Exception e) { Debug.LogException(e); } - finally - { - if (!isLoaded && scene.isLoaded) - EditorSceneManager.CloseScene(scene, true); - } } } private static void ValidateAllAssets(Report report) { ValidateAssetsBytype(report); - - foreach (var pair in _validatorList.AssetValidators) - { - var assets = EditorAssetUtility.LoadAllAssets(pair.Key); - - for (var i = 0; i < assets.Length; i++) - { - try - { - var assetPath = AssetDatabase.GetAssetPath(assets[i]); - var assetGuid = AssetDatabase.GUIDFromAssetPath(assetPath); - ValidateAsset(assets[i], assetGuid, assetPath, pair.Value, report); - } - catch (Exception e) - { - Debug.LogException(e); - } - } - } } private static void ValidateAllPrefabs(Report report) @@ -310,29 +253,6 @@ namespace Module.ProjectValidator.Editor Validate(assetGuid, relativePath, components[i], report); } } - - private static void ValidateAsset(UnityEngine.Object obj, GUID assetGuid, string relativePath, List validators, Report report) - { - using var _ = ListPool.Get(out var results); - - for (var i = 0; i < validators.Count; i++) - { - results.Clear(); - var validator = validators[i]; - validator.ValidatorMethod.Invoke(validator.Validator, new object[] { obj, results }); - - for (var j = 0; j < results.Count; j++) - { - var result = results[j]; - - if (result.Severity == EValidatorSeverity.Valid) - continue; - - var validatorName = ProjectValidatorUtility.GetAssetValidatorName(validator.Validator); - report.Add(assetGuid, relativePath, string.Empty, validatorName, result.Severity, result.Message); - } - } - } private static void ValidateChildren(GameObject gameObject, string relativePath, Report report) { @@ -423,18 +343,8 @@ namespace Module.ProjectValidator.Editor var fieldPath = parentFieldPath; ProjectValidatorUtility.AppendToFieldPath(e.FieldInfo, ref fieldPath); - - if (value is Array arr) - { - for (var j = 0; j < arr.Length; j++) - { - var eObj = arr.GetValue(j); - var fieldPathArrElement = fieldPath; - ProjectValidatorUtility.AppendToFieldPath(j, ref fieldPathArrElement); - Validate(assetGuid, relativePath, fieldPathArrElement, eObj, e.Entry, report); - } - } - else if (value is IEnumerable ie) + + if (value is IEnumerable ie) { var idx = 0; diff --git a/Editor/Validators/Assets.meta b/Editor/Validators/Assets.meta deleted file mode 100644 index a1c08b2..0000000 --- a/Editor/Validators/Assets.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ddbf30cd5a674751be0c125c1f4e917b -timeCreated: 1779623970 \ No newline at end of file diff --git a/Editor/Validators/Assets/AssetValidatorMaterialShader.cs b/Editor/Validators/Assets/AssetValidatorMaterialShader.cs deleted file mode 100644 index f6e072f..0000000 --- a/Editor/Validators/Assets/AssetValidatorMaterialShader.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using UnityEngine.Rendering; - -namespace Module.ProjectValidator.Editor -{ - internal sealed class AssetValidatorMaterialShader : IAssetValidator - { - public void Validate(Material obj, List results) - { - if (obj.shader == null) - results.Add(ValidatorResult.Create(EValidatorSeverity.Error, "Shader is Null")); - else if (!IsCompatible(obj.shader)) - results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"Shader '{obj.shader.name}' is not compatible with render pipeline")); - else if (!obj.shader.isSupported) - results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"Shader '{obj.shader.name}' is not supported")); - else if (ShaderUtil.ShaderHasError(obj.shader)) - results.Add(ValidatorResult.Create(EValidatorSeverity.Error, $"Shader '{obj.shader.name}' has compile errors")); - } - - private static bool IsCompatible(Shader shader) - { - var pipeline = GraphicsSettings.currentRenderPipeline; - - if (pipeline == null) - return true; - - var tagSearch = new ShaderTagId("RenderPipeline"); - var tagPipeline = new ShaderTagId(pipeline.renderPipelineShaderTag); - var hasKeyword = false; - - for (var i = 0; i < shader.passCount; i++) - { - var tagPass = shader.FindPassTagValue(i, tagSearch); - - if (tagPass != ShaderTagId.none) - hasKeyword = true; - - if (tagPass == tagPipeline) - return true; - } - - return !hasKeyword; - } - } -} \ No newline at end of file diff --git a/Editor/Validators/Assets/AssetValidatorMaterialShader.cs.meta b/Editor/Validators/Assets/AssetValidatorMaterialShader.cs.meta deleted file mode 100644 index a1eceb1..0000000 --- a/Editor/Validators/Assets/AssetValidatorMaterialShader.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2218d247daff44bf84629756b63ea650 -timeCreated: 1779623986 \ No newline at end of file diff --git a/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs b/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs deleted file mode 100644 index 37097fa..0000000 --- a/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Rendering; - -namespace Module.ProjectValidator.Editor -{ - internal sealed class AssetValidatorMaterialTexture : IAssetValidator - { - public void Validate(Material obj, List results) - { - if (obj.shader == null) - return; - - var count = obj.shader.GetPropertyCount(); - - for (var i = 0; i < count; i++) - { - var propertyType = obj.shader.GetPropertyType(i); - var propertyFlags = obj.shader.GetPropertyFlags(i); - - if (propertyType != ShaderPropertyType.Texture) - continue; - if ((propertyFlags & (ShaderPropertyFlags.PerRendererData | ShaderPropertyFlags.HideInInspector | ShaderPropertyFlags.NonModifiableTextureData)) != 0) - continue; - - var propertyName = obj.shader.GetPropertyName(i); - var propertyValue = obj.GetTexture(propertyName); - - if (propertyValue == null) - results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"Texture property '{propertyName}' is Null")); - } - } - } -} \ No newline at end of file diff --git a/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs.meta b/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs.meta deleted file mode 100644 index d975053..0000000 --- a/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: cfeb4b29a9cd4ea79c1e9325b8122e17 -timeCreated: 1779627240 \ No newline at end of file diff --git a/Editor/Validators/Attributes/AttributeValidatorObsolete.cs b/Editor/Validators/Attributes/AttributeValidatorObsolete.cs deleted file mode 100644 index 0eb3c19..0000000 --- a/Editor/Validators/Attributes/AttributeValidatorObsolete.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Module.ProjectValidator.Editor -{ - internal sealed class AttributeValidatorObsolete : IAttributeValidator - { - public ValidatorResult Validate(ObsoleteAttribute attribute, object value) - { - return ValidatorResult.Create(EValidatorSeverity.Error, "Obsolete"); - } - } -} \ No newline at end of file diff --git a/Editor/Validators/Attributes/AttributeValidatorObsolete.cs.meta b/Editor/Validators/Attributes/AttributeValidatorObsolete.cs.meta deleted file mode 100644 index 2a54b7b..0000000 --- a/Editor/Validators/Attributes/AttributeValidatorObsolete.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 982ac4e898cc2ca438e98a2f0034a8d3 \ No newline at end of file diff --git a/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs b/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs index eaf89a1..1ea0509 100644 --- a/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs +++ b/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Reflection; +using System.Collections.Generic; using UnityEngine; using UnityEngine.Pool; @@ -30,7 +28,7 @@ namespace Module.ProjectValidator.Editor } else { - if (count > 1 && IsMultipleComponentsAllowed(type)) + if (count > 1) results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"GameObject has duplicate '{type.Name}' ({count}) components")); type = t; @@ -38,13 +36,8 @@ namespace Module.ProjectValidator.Editor } } - if (count > 1 && IsMultipleComponentsAllowed(type)) + if (count > 1) results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"GameObject has duplicate '{type.Name}' ({count}) components")); } - - private static bool IsMultipleComponentsAllowed(Type type) - { - return type.GetCustomAttribute(true) == null; - } } } \ No newline at end of file diff --git a/Editor/Validators/GameObject/GameObjectValidatorTransform.cs b/Editor/Validators/GameObject/GameObjectValidatorTransform.cs deleted file mode 100644 index 58b6f92..0000000 --- a/Editor/Validators/GameObject/GameObjectValidatorTransform.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace Module.ProjectValidator.Editor -{ - internal sealed class GameObjectValidatorTransform : IGameObjectValidator - { - public void Validate(GameObject gameObject, List results) - { - var transform = gameObject.transform; - var lp = transform.localPosition; - var lr = transform.localRotation; - var ls = transform.localScale; - - if (IsInvalid(lp.x) || IsInvalid(lp.y) || IsInvalid(lp.z)) - results.Add(ValidatorResult.Create(EValidatorSeverity.Error, $"Local position '{lp}' is invalid")); - if (IsInvalid(lr.x) || IsInvalid(lr.y) || IsInvalid(lr.z) || IsInvalid(lr.w)) - results.Add(ValidatorResult.Create(EValidatorSeverity.Error, $"Local rotation '{lr}' is invalid")); - if (IsInvalid(ls.x) || IsInvalid(ls.y) || IsInvalid(ls.z)) - results.Add(ValidatorResult.Create(EValidatorSeverity.Error, $"Local scale '{ls}' is invalid")); - } - - private static bool IsInvalid(float value) - { - return float.IsNaN(value) || float.IsInfinity(value); - } - } -} \ No newline at end of file diff --git a/Editor/Validators/GameObject/GameObjectValidatorTransform.cs.meta b/Editor/Validators/GameObject/GameObjectValidatorTransform.cs.meta deleted file mode 100644 index 89d7bda..0000000 --- a/Editor/Validators/GameObject/GameObjectValidatorTransform.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 727d5de59b004deb8c192337bcee132e -timeCreated: 1779628852 \ No newline at end of file diff --git a/Editor/Window/EditorProjectValidatorWindow.cs b/Editor/Window/EditorProjectValidatorWindow.cs index 1d01017..4989d7d 100644 --- a/Editor/Window/EditorProjectValidatorWindow.cs +++ b/Editor/Window/EditorProjectValidatorWindow.cs @@ -8,18 +8,12 @@ namespace Module.ProjectValidator.Editor { internal sealed class EditorProjectValidatorWindow : EditorWindow { - private VisualElement _groupWarnings; - private Label _labelWarnings; - - private VisualElement _groupErrors; - private Label _labelErrors; - private MultiColumnTreeView _treeView; private string _searchFilter; - + private readonly List> _list = new(); private readonly List> _filteredList = new(); - + public void CreateGUI() { var root = rootVisualElement; @@ -27,19 +21,9 @@ namespace Module.ProjectValidator.Editor root.styleSheets.Add(EditorAssetUtility.LoadFirstAsset("StyleSheetEditorProjectValidatorWindow")); root.Add(asset.Instantiate()); - _groupWarnings = root.Q("status-warnings"); - _labelWarnings = _groupWarnings.Q