1
--------sofware version--------
Unity version : 2020.2.7f1
IDE : Rider 2020.3.2
--------sofware version--------

当我尝试将 Unity 与 Source Generator 结合时遇到问题。

我能够构建一个源生成器并将生成的分析器放在 Unity 中,我的 IDE 能够获取生成的代码(语法突出显示正在工作),但是当 unity 编译它时它无法找到相关的代码,因此给出编译错误。 屏幕截图,IDE 已正确突出显示,但 Unity 控制台中出现错误

似乎人们遇到了类似的问题,但无法找到解决方案。我试图通过第三方库强制 Unity 使用更新版本的 Compiler(3.10),但这似乎也不能解决问题。

据我所知,问题似乎是 Unity 使用的编译器已经过时,但我认为如果是这种情况,我强迫它使用更新版本的编译器的技巧应该可以解决问题。

源生成器无法正常工作的原因是什么,我该如何解决?我不介意使用黑客,因为该项目不是商业的。


更新:

我试图通过在源生成器运行时写入文件来确认我的分析器在某个时间点正在运行。我可以看到我的文件被写入配置的目录,我假设我的生成器在某个时候被使用。

obj但是我在Unity的文件夹中看不到任何生成的源代码。这与我在 Unity 之外运行 Source Generator 时的行为不同。

这背后的可能原因是什么?


更新 2:

为了更清楚(感谢@david-ao 的建议),我认为包含修剪生成的 csproj 可能会有所帮助(在 Unity 中 csproj 是自动生成的,因此我覆盖了项目生成过程并添加了一些必要的设置):

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Analyzer Include="Assets/Analyzers/NoobJet.Analyzer.dll" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <ItemGroup>
    <PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="3.10.0-1.final">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>
  <PropertyGroup>
  </PropertyGroup>
    <PropertyGroup>
      <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
      <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)..\..\Assets\GeneratedFiles</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
</Project>

我试图通过上述设置实现以下结果:

  1. 编译时引用分析器
  2. 将生成的文件输出到适当的目录(我故意希望它不在obj文件夹中)
  3. 使用3.10.0-1.final编译器。

如果有帮助,这里是完整生成的 csproj 文件。

4

2 回答 2

3

源生成器是 .NET 5 的一项功能。Unity 不能以 .NET 5 为目标,因此使用最新的编译器对您没有帮助;请注意您链接到的 GitHub 存储库中的此注释。

Unity 甚至不支持 .NET Core 3.1 和 .NET 5 没有 LTS 毫无价值,因此我们不太可能在不久的将来看到对此的支持。

于 2021-03-21T08:38:06.810 回答
0

源代码生成器是C#9 功能,并与编译器严格关联。

更新:

您可以添加对预编译 dll 的引用吗?您在针对 c#9 的 netstandard2.0 上创建源代码生成器,因此它完全由您控制。如果您可以告诉 Unity 引用的 dll 是一个分析器,并且您已经设法强制使用针对 C#9 的较新编译器,那么您至少需要满足最低要求才能使其正常工作,那么 Unity 中的情况当然有所不同,所以这还不够,但至少是必要的

结束更新

我不是 Unity 开发人员,所以我不能 100% 确定这是否符合您的需求,但我会向您展示在 VSCode 和 Visual Studio 中为我解决了哪些问题,但存在类似问题,不知何故,源生成器正在运行,但 IDE 抱怨

UPD:我添加了我的 csproj 的全部内容,以显示我需要哪些其他参考资料才能使一切正常工作。

源代码生成器项目必须以 netstandard2.0 为目标,但您必须将语言版本显式为 netstandard2.0,默认目标为 C#7.3

      <Project Sdk="Microsoft.NET.Sdk">
       <PropertyGroup>
         <TargetFramework>netstandard2.0</TargetFramework>
         <LangVersion>latest</LangVersion>
       </PropertyGroup>
       <ItemGroup>
         <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
           <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
           <PrivateAssets>all</PrivateAssets>
         </PackageReference>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.9.0" />
  </ItemGroup>
</Project>

我使用 net5.0 并且一切正常,但 ide 抱怨,我的理解是 IDE 需要它是 2.0,因为它被视为分析器。

我的消费项目是 net5.0,所以默认情况下我启用了 C#9,你应该检查你的消费项目是否使用 C#9 并引用项目或 dll 作为分析器

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <RootNamespace>use_generator</RootNamespace>
  </PropertyGroup>

<ItemGroup>
    <ProjectReference Include="..\generator\generator.csproj"
    ReferenceOutputAssembly="false"
    OutputItemType="Analyzer" />
  </ItemGroup>

<ItemGroup>
  <PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="3.9.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
  </PackageReference>
</ItemGroup>

</Project>

最重要的是,我必须关闭并重新打开 Visual Studio 才能捕获更改,并且每次更改源生成器时都必须这样做,该功能正在运行,但工具仍处于早期阶段

于 2021-03-28T11:31:51.343 回答