文档

Unity Engine

Unity Engine

Creating custom analyzers

Add your own custom analyzers to Project Auditor.
阅读时间4 分钟最后更新于 17 小时前

Project Auditor provides an API for creating custom analyzers tailored to the needs of your project.
Internally, Project Auditor creates and maintains the following modules:
  • Animation
  • Assets
  • AudioClip
  • BuildReport
  • Code
  • Mesh
  • Packages
  • Settings
  • Shader
  • SpriteAtlas
  • Texture
Every module has a corresponding class inheriting from
ModuleAnalyzer
which declares an
Analyze
method which takes a type inheriting from
AnalysisContext
. During analysis, the module uses reflection to detect and create instances of any Analyzer classes inheriting from its corresponding
ModuleAnalyzer
, then constructs
AnalysisContext
objects and passes them to the Analyzers.

Create an analyzer

The following is an example showing how to create a custom Analyzer. Imagine a texture-heavy 2D game with a pixel art visual style. In such a project it might be desirable to enforce maximum sizes for sprite texture assets to help manage memory and to enforce a consistent visual resolution.
The example script demonstrates how to do the following:
  • Declare and register a
    Descriptor
    , including its custom
    Fixer
    .
  • Use
    DiagnosticParameterAttribute
    to declare a diagnostic parameter for use during analysis.
  • Access the contents of the
    context
    structure passed to it to decide whether to report an issue.
  • Create an issue, including specifying the
    IssueCategory
    which dictates the view in which the issue appears and the information that is displayed in the Issue table.
using System;using System.Collections.Generic;using Unity.ProjectAuditor.Editor;using Unity.ProjectAuditor.Editor.Core;using UnityEditor;// Inherit from TextureModuleAnalyzer to allow TextureModule to create and run an// instance of this analyzer.class CustomTextureAnalyzer : TextureModuleAnalyzer{ // Define our custom maximum sprite size const int k_MaxSpriteSize = 1024; // Data for constructing a descriptor. const string k_SpriteTooBigId = "PAA9000"; // Make sure this ID is unique. const string k_Title = "(Custom) Texture: Oversized Sprite"; const Areas k_ImpactedAreas = Areas.Memory | Areas.Quality; const string k_Description = "The source texture for this Sprite is larger than the limit specified by " + "the game's art direction. Oversized textures can take up too much memory " + "and compromise visual style."; const string k_Recommendation = "Resize the source texture, or set the <b>Max Size</b> option in the " + "Texture Import Settings to a suitable value."; // Declare a Descriptor to describe the issue we want to report. static readonly Descriptor k_CustomSpriteTooBigDescriptor = new Descriptor ( k_SpriteTooBigId, k_Title, k_ImpactedAreas, k_Description, k_Recommendation ) { // As well as the constructor parameters above, this area can be used to set // the values of other Descriptor fields. // Project Auditor will format this message using the Name that's passed into // CreateIssue. MessageFormat = "Sprite '{0}' is oversized", // Optionally declare a delegate to fix the issue in a single button click. Fixer = (issue, analysisParams) => { var textureImporter = AssetImporter.GetAtPath(issue.RelativePath) as TextureImporter; if (textureImporter != null) { textureImporter.maxTextureSize = k_MaxSpriteSize; textureImporter.SaveAndReimport(); } } }; // Declare m_CustomSpriteSizeLimit as a DiagnosticParam. Give the parameter a // unique name and a sensible default. [DiagnosticParameter("CustomSpriteSizeLimit", "Sprite Size Limit", "Warn if any sprites have a width or height greater than this value.", k_MaxSpriteSize)] int m_CustomSpriteSizeLimit; // Override the initialize method in order to pass the custom Descriptor to the // registerDescriptor Action so that ProjectAuditor knows about it. public override void Initialize(Action<Descriptor> registerDescriptor) { registerDescriptor(k_CustomSpriteTooBigDescriptor); } // Implementation of the custom Analyze coroutine method. In the case of a class // inheriting from TextureModuleAnalyzer, the AnalysisContext passed to this // method is a TextureAnalysisContext. public override IEnumerable<ReportItem> Analyze(TextureAnalysisContext context) { // Check to see if a texture is treated as a sprite, and check its dimensions if (context.Importer.textureType == TextureImporterType.Sprite && (context.Texture.width > m_CustomSpriteSizeLimit || context.Texture.height > m_CustomSpriteSizeLimit)) { // Create the issue with the correct category, DescriptorId, name and path yield return context.CreateIssue(IssueCategory.AssetIssue, k_CustomSpriteTooBigDescriptor.Id, context.Name) .WithLocation(context.Importer.assetPath); } }}

Custom analyzer output

Debugging slow analyzers

The analysis for some issues might take a long time to run, particularly in a large project. The
Descriptor
for such issues might declare
Descriptor.IsEnabledByDefault
to be false to stop them running when running Project Auditor interactively in the Editor.
When running Project Auditor in a CI/CD environment you can re-enable analysis for these descriptors. Use
AnalysisParams.WithAdditionalDiagnosticRules
to add temporary
Rule
instances to increase the
Severity
of a Descriptor to anything other than
Severity.None
to re-enable analysis in this context.

Writing Descriptor text

Use the following guidelines when writing the strings that appear in Descriptors for the Issues the tool reports:
  • Use bold for the name of APIs and settings options in both the description and the recommendation. Do this by adding
    <b>
    and
    </b>
    tags before and after the name.
  • Don’t use rich text in title or
    messageFormat
    strings. No
    <b>
    bold
    </b>
    tags, for example. These fields don’t support rich text in the UI so it will look bad.

Additional resources