You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为System.Reflection调用的代码片段添加UnityEngine程序集引用

解决Unity运行时C#编译引用UnityEngine程序集的问题

核心问题根源

Unity的核心程序集(如UnityEngine.dll)在打包后的游戏中并非以普通文件形式存放在文件系统中,而是被嵌入到Unity的加载体系里。通过AppDomain.CurrentDomain.GetAssemblies()获取的Unity相关Assembly对象,其Location属性通常为空或指向无效路径,导致旧版编译器(如CSharpCodeProvider)无法找到对应的元数据文件,从而抛出CS0006错误。

可行解决方案

1. 动态获取程序集绝对路径(适配编辑器/打包环境)

针对旧版CSharpCodeProvider,需根据运行环境拼接UnityEngine.dll的绝对路径,添加到引用列表:

using System.IO;
#if UNITY_EDITOR
using UnityEditor;
#endif

// 构建UnityEngine.dll的绝对路径
string unityEnginePath;
#if UNITY_EDITOR
unityEnginePath = Path.Combine(EditorApplication.applicationContentsPath, "Managed", "UnityEngine.dll");
#else
unityEnginePath = Path.Combine(Application.dataPath, "Managed", "UnityEngine.dll");
#endif

// 添加到引用列表
references.Add(unityEnginePath);

此方法依赖文件系统中存在对应的DLL文件,在编辑器和标准打包环境下均有效。

2. 切换到Roslyn编译(推荐长期方案)

旧版CSharpCodeProvider功能受限,建议改用微软官方的Roslyn编译器(Microsoft.CodeAnalysis.CSharp),它支持直接引用内存中的程序集元数据,无需依赖文件路径:

  1. 在Unity项目中添加兼容的Microsoft.CodeAnalysis.CSharp和Microsoft.CodeAnalysis NuGet包(选择适配.NET Framework 4.x的版本)。
  2. 替换编译逻辑为以下代码:
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

// 构建程序集引用列表
var references = AppDomain.CurrentDomain.GetAssemblies()
    .Where(a => !a.IsDynamic && !string.IsNullOrEmpty(a.Location))
    .Select(a => MetadataReference.CreateFromFile(a.Location))
    .ToList();

// 单独处理UnityEngine等无有效路径的程序集
Assembly unityEngineAssembly = typeof(GameObject).Assembly;
using (Stream stream = unityEngineAssembly.GetManifestResourceStream($"{unityEngineAssembly.GetName().Name}.dll"))
{
    if (stream != null)
    {
        references.Add(MetadataReference.CreateFromStream(stream));
    }
}

// 待编译代码示例
string code = @"
using UnityEngine;
public class RuntimeMod
{
    public void Execute()
    {
        Debug.Log(""模组代码执行成功"");
    }
}";

// 编译执行
var syntaxTree = CSharpSyntaxTree.ParseText(code);
var compilation = CSharpCompilation.Create(
    "RuntimeModAssembly",
    syntaxTrees: new[] { syntaxTree },
    references: references,
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

using (var ms = new MemoryStream())
{
    var emitResult = compilation.Emit(ms);
    if (emitResult.Success)
    {
        ms.Seek(0, SeekOrigin.Begin);
        Assembly modAssembly = Assembly.Load(ms.ToArray());
        Type modType = modAssembly.GetType("RuntimeMod");
        object modInstance = Activator.CreateInstance(modType);
        modType.GetMethod("Execute")?.Invoke(modInstance, null);
    }
    else
    {
        // 输出编译错误
        foreach (var diagnostic in emitResult.Diagnostics)
        {
            UnityEngine.Debug.LogError(diagnostic.ToString());
        }
    }
}

常见错误规避

  • 不要直接将"UnityEngine"添加到引用列表,编译器需要的是DLL的绝对路径或元数据,而非程序集名称。
  • 打包后需确保游戏Data/Managed目录下存在UnityEngine.dll(Unity默认会自动打包该文件)。

内容的提问来源于stack exchange,提问作者RiskOfAdventure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:50:21