diff --git a/Editor/Objects/Report.cs b/Editor/Objects/Report.cs index 278955a..5b68f9f 100644 --- a/Editor/Objects/Report.cs +++ b/Editor/Objects/Report.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using UnityEditor; using UnityEngine; - namespace Module.ProjectValidator.Editor { internal sealed class Report @@ -64,7 +64,7 @@ namespace Module.ProjectValidator.Editor public bool TryGetSeverityFor(string guid, out MappingEntry mapping) { - if (UnityEngine.GUID.TryParse(guid, out var assetGuid) && _assetToSeverityMapping.TryGetValue(assetGuid, out mapping)) + if (GUID.TryParse(guid, out var assetGuid) && _assetToSeverityMapping.TryGetValue(assetGuid, out mapping)) return true; mapping = new MappingEntry(); diff --git a/Editor/ValidatorRunner.cs b/Editor/ValidatorRunner.cs index 5314e60..b69797a 100644 --- a/Editor/ValidatorRunner.cs +++ b/Editor/ValidatorRunner.cs @@ -179,12 +179,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,14 +194,16 @@ 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); + } } } @@ -421,8 +423,18 @@ namespace Module.ProjectValidator.Editor var fieldPath = parentFieldPath; ProjectValidatorUtility.AppendToFieldPath(e.FieldInfo, ref fieldPath); - - if (value is IEnumerable ie) + + 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) { var idx = 0; diff --git a/Editor/Validators/Assets/AssetValidatorMaterialShader.cs b/Editor/Validators/Assets/AssetValidatorMaterialShader.cs index 6a0dfce..f6e072f 100644 --- a/Editor/Validators/Assets/AssetValidatorMaterialShader.cs +++ b/Editor/Validators/Assets/AssetValidatorMaterialShader.cs @@ -28,16 +28,20 @@ namespace Module.ProjectValidator.Editor 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 false; + return !hasKeyword; } } } \ No newline at end of file diff --git a/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs b/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs index 9f07b96..37097fa 100644 --- a/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs +++ b/Editor/Validators/Assets/AssetValidatorMaterialTexture.cs @@ -16,10 +16,13 @@ namespace Module.ProjectValidator.Editor 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); diff --git a/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs b/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs index 1ea0509..eaf89a1 100644 --- a/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs +++ b/Editor/Validators/GameObject/GameObjectValidatorDuplicateComponents.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Reflection; using UnityEngine; using UnityEngine.Pool; @@ -28,7 +30,7 @@ namespace Module.ProjectValidator.Editor } else { - if (count > 1) + if (count > 1 && IsMultipleComponentsAllowed(type)) results.Add(ValidatorResult.Create(EValidatorSeverity.Warning, $"GameObject has duplicate '{type.Name}' ({count}) components")); type = t; @@ -36,8 +38,13 @@ namespace Module.ProjectValidator.Editor } } - if (count > 1) + if (count > 1 && IsMultipleComponentsAllowed(type)) 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/Window/EditorProjectValidatorWindow.cs b/Editor/Window/EditorProjectValidatorWindow.cs index 7966bc8..1d01017 100644 --- a/Editor/Window/EditorProjectValidatorWindow.cs +++ b/Editor/Window/EditorProjectValidatorWindow.cs @@ -8,12 +8,18 @@ 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; @@ -21,6 +27,15 @@ namespace Module.ProjectValidator.Editor root.styleSheets.Add(EditorAssetUtility.LoadFirstAsset("StyleSheetEditorProjectValidatorWindow")); root.Add(asset.Instantiate()); + _groupWarnings = root.Q("status-warnings"); + _labelWarnings = _groupWarnings.Q