.net 有办法在Unity中使用Roslyn吗?

dluptydi  于 2023-11-20  发布在  .NET
关注(0)|答案(2)|浏览(192)

所以,我有这个项目,我们将调用X. X是在.NET Core 3.1中开发的控制台应用程序,我想给予这个应用程序一个与Unity的接口。这个应用程序的核心部分是基于一些文本的代码的动态生成。在X中,我使用Roslyn来完成。我已经通过NuGet安装了Microsoft.CodeAnlysis.CSharp.Scripting包和它携带的所有包,它工作得很好。在Unity中“转换”项目(在播放器设置中设置为.NET Framework编译)我做了我认为是最简单的事情。我将X文件夹中的所有脚本复制并粘贴到Unity Asset文件夹中,并开始重写需要重写的内容。一切都很顺利,直到我到达代码生成部分。经过一番折腾,我发现了NuGetForUnity,我用它来获取我在最新版本的X中使用的相同NuGet包。安装了所有东西后,我尝试运行我的应用程序。我得到了这个错误:

  1. > System.NotImplementedException: The method or operation is not implemented.
  2. at System.Runtime.Loader.AssemblyLoadContext.LoadFromStream (System.IO.Stream assembly, System.IO.Stream assemblySymbols) [0x00000] in <b903c2b7b82245b2878c8afa0d6b7576>:0
  3. at Microsoft.CodeAnalysis.Scripting.Hosting.CoreAssemblyLoaderImpl.LoadFromStream (System.IO.Stream peStream, System.IO.Stream pdbStream) [0x00000] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0
  4. at Microsoft.CodeAnalysis.Scripting.Hosting.InteractiveAssemblyLoader.LoadAssemblyFromStream (System.IO.Stream peStream, System.IO.Stream pdbStream) [0x00000] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0
  5. 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
  6. 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
  7. at Microsoft.CodeAnalysis.Scripting.Script`1[T].GetExecutor (System.Threading.CancellationToken cancellationToken) [0x0002b] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0
  8. at Microsoft.CodeAnalysis.Scripting.Script`1[T].CreateDelegate (System.Threading.CancellationToken cancellationToken) [0x0000d] in <7da58dd2a6fc48459bcdbf30dedfadbc>:0
  9. at CodeGenerator.GenericExternalBuilder[T] (System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue] coll) [0x008c2] in C:\Users\User\Documents\uXCOM\Assets\Scripts\CodeGenerator.cs:198
  10. at (wrapper dynamic-method) System.Object.CallSite.Target(System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,System.Type,object)
  11. at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1] (System.Runtime.CompilerServices.CallSite site, T0 arg0, T1 arg1) [0x00113] in <dab7f68612224ba3ae40f651d44f9d4c>:0
  12. at CodeGenerator.InitializeAllExternals () [0x00026] in C:\Users\User\Documents\uXCOM\Assets\Scripts\CodeGenerator.cs:52
  13. UnityEngine.Debug:LogError (object)
  14. XCOM.XLogger:FixedUpdate () (at Assets/Scripts/XLogger.cs:100)

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

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


这抛出了相同类型的异常,只是有点不同:

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


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

jxct1oxe

jxct1oxe1#

几年前我做了和你一样的事情。我使用API(类CSharpCodeProvider和类SharperParameters)来做到这一点。我确实认为你可以尝试一下。

wvmv3b1j

wvmv3b1j2#

我在2022年8月做了这件事,也许现在更容易了。但这些帮助我让它工作起来:
如何在Roslyn动态编译的代码中引用另一个DLL
How do you add references to types compiled in a memory stream using Roslyn?
C# reflection - load assembly and invoke a method if it exists
这可能需要你几个星期的时间来让它工作。
如果您的目标客户是IL 2CPP,您将需要查看https://github.com/scottyboy805/dotnow-interpreter/wiki/Roslyn-C%23-Integration
或者,Unity Asset Store中有Roslyn C#(可能在24小时内开始销售)--利用它可以将时间缩短一半。https://forum.unity.com/threads/released-roslyn-c-runtime-c-compiler.651505/page-5#post-8102249
有大量的极端情况(如脚本中的“是否要利用NewtonsoftIdeJson”)会根据您的需要增加额外的挑战。

相关问题