Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Roslyn Analyzer for Unity package

Discussion in 'Scripting' started by lweist3317, Mar 23, 2024.

  1. lweist3317

    lweist3317

    Joined:
    Oct 12, 2017
    Posts:
    34
    Im currently working on a package that provides a framework, and want to write some custom DiagnosticAnalyzers for the correct usage of it.
    Ive written a few for non-Unity projects before, so my question is not about the analyzers themselves, but rather about how to best integrate them within a Unity project.

    As far as official documentation goes, this page is all I could find.
    On there, they suggest you build the analyzer .dll outside of Unity, and then paste it into your project.
    That does work, but since im building an analyzer for a framework ive made I'd ideally want to be able to directly reference the frameworks classes instead of just relying on strings, to make it more resilient to namespace changes etc.

    As for directly writing the analyzer in the unity project, from what I could find Unity does not allow for building .dlls.

    This is the ideal project structure Im trying to achieve (but Ill take anything that allows my analyzer to directly reference the framework classes):

    Assets/
    |- MyFramework/
    | |- MyFramework
    | | |- MyFramework.asmdef
    | | |- Framework classes...
    | |- MyFrameworkAnalyzer/
    | | |- MyFrameworkAnalyzer.asmdef
    | | |- MyAnalyzer.cs
    | | |- MyFrameworkAnalyzer.dll
    |- Scripts
    | |- SomeOtherAssembly.asmdef
    | |- SomeClass.cs

    where MyFramewrokAnalyzer.asmdef of course references MyFramework.asmdef.
    SomeOtherAssembly would then reference both of the framework assemblies, and SomeClass could use the framework classes with the custom diagnostics.
     
  2. DrummerB

    DrummerB

    Joined:
    Dec 19, 2013
    Posts:
    139
    Did you find a solution? I am facing the same issue currently.

    Currently I am experimenting with a setup that looks something like this:

    Code (csharp):
    1. Assets/
    2. Packages/
    3.   Foo // a local package
    4.     Scripts
    5.       Foo.asmdef
    6.       ...
    7.     Tests
    8.       Foo.Tests.asmdef
    9.       ...
    10.     Analyzers
    11.       Foo.Analyzers.asmdef
    12.       ...
    This would result in the analyzer DLL being compiled by Unity's compilation pipeline to Libraries/ScriptAssemblies/ Foo.Analyzers.dll.

    I was planning to then use some callback and timestamp comparison to automatically move the DLL back into the Packages/Foo/Scripts folder, because according to the documentation, this would result in the analyzer being applied to users of the package:

    If an analyzer is in a folder that contains an assembly definition, or a subfolder of such a folder, the analyzer only applies to the assembly generated from that assembly definition, and to any other assembly that references it.

    I think this more or less would work.

    However, currently I am getting an error that I could not yet solve:

    Foo.Analyzers references netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51. A roslyn analyzer should reference netstandard version 2.0

    Might be worth exploring a manual compilation of the analyzer using UnityEditor.Compilation.AssemblyBuilder.
     
  3. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    741
    You’re not really meant to compile analyzers from within Unity. Also, AssemblyBuilder is obsolete in Unity 6. Instead, you should create an appropriate .NET Standard 2.0 project and compile it with a recent .NET SDK, and move it into place as desired. Here is an example of such a project:
    https://github.com/needle-mirror/co...ource~/SystemGenerator/SystemGenerator.csproj

    As for referencing existing code in an analyzer, that code would itself need to be shipped as a compiled assembly in order for the built analyzer to be able to reference it.
     
  4. DrummerB

    DrummerB

    Joined:
    Dec 19, 2013
    Posts:
    139
    I understand that this is what Unity is recommending currently, but this is just a hacky workaround at best.

    How do you solve a setup where you have multiple projects and packages in a mono repo and want to include an analyzer in one of the packages, so that users of the package are alerted to incorrect use of that package? Manually building the analyzer and embedding the DLL into the project is ugly for several reasons.

    You generally don't want to commit binaries that are derived from source within the repo. And editing the analyzer code would require a separate workflow from editing package or project code.

    In an ideal solution, the analyzer would be committed as code, the package (and its analyzer) would be referenced in a project, the analyzer would be automatically built whenever its source changes and then updated in the project to be used for analysis.