有没有办法在Unity中使用Roslyn?

问题描述 投票:0回答:1

所以,我有一个我们称之为 X 的项目。X 是一个在 .NET Core 3.1 中开发的控制台应用程序,我想为这个应用程序提供一个与 Unity 的接口。 该应用程序的核心部分是基于某些文本动态生成代码。在 X 中,我使用 Roslyn 来做到这一点。我已经通过 NuGet 安装了 Microsoft.CodeAnthesis.CSharp.Scripting 包及其继承的所有包,并且运行良好。 在 Unity 中“转换”项目(在“播放器设置”中设置为针对 .NET Framework 进行编译)我做了我认为最简单的事情。我将 X 文件夹中的所有脚本复制并粘贴到 Unity Asset 文件夹中,然后开始重写需要重写的内容。一切都很顺利,直到我进入代码生成部分。经过一番摸索后,我发现了 NuGetForUnity,我用它来获取我在最新版本的 X 中使用的相同 NuGet 包。安装完所有内容后,我尝试运行我的应用程序。我收到了这个错误:

> System.NotImplementedException: The method or operation is not implemented.
  at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream (System.IO.Stream assembly, System.IO.Stream assemblySymbols) [0x00000] in <b903c2b7b82245b2878c8afa0d6b7576>:0 
  at Microsoft.CodeAnalysis.Scripting.Hosting.CoreAssemblyLoaderImpl.LoadFromStream (System.IO.Stream peStream, System.IO.Stream pdbStream) [0x00000] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0 
  at Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader.LoadAssemblyFromStream (System.IO.Stream peStream, System.IO.Stream pdbStream) [0x00000] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0 
  at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.Build[T] (Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, System.Boolean emitDebugInformation, System.Threading.CancellationToken cancellationToken) [0x000c6] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0 
  at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T] (Microsoft.CodeAnalysis.Scripting.ScriptCompiler compiler, Microsoft.CodeAnalysis.Compilation compilation, System.Boolean emitDebugInformation, System.Threading.CancellationToken cancellationToken) [0x00026] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0 
  at Microsoft.CodeAnalysis.Scripting.Script`1[T].GetExecutor (System.Threading.CancellationToken cancellationToken) [0x0002b] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0 
  at Microsoft.CodeAnalysis.Scripting.Script`1[T].CreateDelegate (System.Threading.CancellationToken cancellationToken) [0x0000d] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0 
  at CodeGenerator.GenericExternalBuilder[T] (System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue] coll) [0x008c2] in C:\Users\User\Documents\uXCOM\Assets\Scripts\CodeGenerator.cs:198 
  at (wrapper dynamic-method) System.Object.CallSite.Target(System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,System.Type,object)
  at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1] (System.Runtime.CompilerServices.CallSite site, T0 arg0, T1 arg1) [0x00113] in <dab7f68612224ba3ae40f651d44f9d4c>:0 
  at CodeGenerator.InitializeAllExternals () [0x00026] in C:\Users\User\Documents\uXCOM\Assets\Scripts\CodeGenerator.cs:52 
UnityEngine.Debug:LogError (object)
XCOM.XLogger:FixedUpdate () (at Assets/Scripts/XLogger.cs:100)

真正让我烦恼的是主要异常是 NotImplementedException。我的第一个想法是最新版本不是稳定的,所以我通过 NuGetForUnity 降级,但抛出了另一个异常(我没有它,但如果有用的话我会提供它)。之后我尝试了所有我能想到的方法:降级到我在 X 中使用的版本,通过 .unitypackage 安装相同的包,不同版本的包,在播放器设置中将编译器版本切换到 .NET Standard 2.1,但是没有任何效果。 我将留下一段抛出相同异常的代码,以便在您的项目中可以重现:

private void Test()
{
    string code = "{ int a = 1; int b = 3; return a + b; }";
    ScriptRunner<int> script = CSharpScript.Create<int>(code).CreateDelegate();
    Debug.Log(script.Invoke());
}

这会引发相同类型的异常,只是有点不同:

> NotImplementedException: The method or operation is not implemented.
System.Runtime.Loader.AssemblyLoadContext.LoadFromStream (System.IO.Stream assembly, System.IO.Stream assemblySymbols) (at <b903c2b7b82245b2878c8afa0d6b7576>:0)
Microsoft.CodeAnalysis.Scripting.Hosting.CoreAssemblyLoaderImpl.LoadFromStream (System.IO.Stream peStream, System.IO.Stream pdbStream) (at <7da58dd2a6fc48459bcdbf30dedfadbc>:0)
Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader.LoadAssemblyFromStream (System.IO.Stream peStream, System.IO.Stream pdbStream) (at <7da58dd2a6fc48459bcdbf30dedfadbc>:0)
Microsoft.CodeAnalysis.Scripting.ScriptBuilder.Build[T] (Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.DiagnosticBag diagnostics, System.Boolean emitDebugInformation, System.Threading.CancellationToken cancellationToken) (at <7da58dd2a6fc48459bcdbf30dedfadbc>:0)
Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T] (Microsoft.CodeAnalysis.Scripting.ScriptCompiler compiler, Microsoft.CodeAnalysis.Compilation compilation, System.Boolean emitDebugInformation, System.Threading.CancellationToken cancellationToken) (at <7da58dd2a6fc48459bcdbf30dedfadbc>:0)
Microsoft.CodeAnalysis.Scripting.Script`1[T].GetExecutor (System.Threading.CancellationToken cancellationToken) (at <7da58dd2a6fc48459bcdbf30dedfadbc>:0)
Microsoft.CodeAnalysis.Scripting.Script`1[T].CreateDelegate (System.Threading.CancellationToken cancellationToken) (at <7da58dd2a6fc48459bcdbf30dedfadbc>:0)
MainScript.Test () (at Assets/Scripts/MainScript.cs:33)
MainScript.Start () (at Assets/Scripts/MainScript.cs:22)

我期望它做的是在编辑器控制台 4 上打印。

c# .net unity-game-engine roslyn
1个回答
0
投票

几年前我也做过和你一样的事情。我使用 API 类 CSharpCodeProvider 和 CompilerParameters 来执行此操作。我觉得你可以尝试一下。

© www.soinside.com 2019 - 2024. All rights reserved.