Unity中使用Roslyn动态代码生成遇NotImplementedException问题求助
解决Unity中Roslyn脚本编译的NotImplementedException问题
问题根源
Unity使用的Mono/.NET Framework运行时未实现System.Runtime.Loader.AssemblyLoadContext.LoadFromStream方法,而新版Roslyn Scripting包默认依赖该API,导致动态编译后加载程序集时抛出异常。
解决方案
自定义InteractiveAssemblyLoader,绕过AssemblyLoadContext,直接通过AppDomain加载编译后的程序集:
1. 实现自定义加载器
using System; using System.IO; using Microsoft.CodeAnalysis.Scripting.Hosting; public class UnityAssemblyLoader : InteractiveAssemblyLoader { protected override void LoadAssemblyFromStream(Stream peStream, Stream pdbStream) { // 将PE流转换为字节数组 byte[] peBytes = new byte[peStream.Length]; peStream.Read(peBytes, 0, peBytes.Length); // 加载程序集到当前AppDomain AppDomain.CurrentDomain.Load(peBytes); // 可选:加载PDB符号文件 if (pdbStream != null) { byte[] pdbBytes = new byte[pdbStream.Length]; pdbStream.Read(pdbBytes, 0, pdbBytes.Length); AppDomain.CurrentDomain.Load(pdbBytes); } } }
2. 修改测试代码使用自定义加载器
private void Test() { string code = "{ int a = 1; int b = 3; return a + b; }"; // 指定自定义加载器创建脚本 var script = CSharpScript.Create<int>(code, options: ScriptOptions.Default.WithLoader(new UnityAssemblyLoader())); var runner = script.CreateDelegate(); Debug.Log(runner.Invoke()); }
额外注意事项
- Roslyn版本适配:避免使用4.x+的最新Roslyn包,选择兼容.NET Framework 4.x的3.x系列版本(例如
Microsoft.CodeAnalysis.CSharp.Scripting3.8.0),减少API不兼容风险。 - Unity编译设置:保持Player Settings中编译选项为
.NET Framework,编辑器模式下测试更稳定,发布版本需确认程序集加载权限。 - 运行时限制:打包后的Unity应用可能存在代码签名或沙箱限制,动态编译功能仅建议在编辑器或允许自定义代码的场景中使用。
内容的提问来源于stack exchange,提问作者MrBott_a
相关产品推荐
相关产品推荐

