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

Unity跨程序DLL引用冲突及Android动态编译目录异常求助

解决方案:解决Unity Android动态编译路径问题与DLL重复引用冲突

一、修复Android上的DirectoryNotFoundException

在Android平台,Unity应用处于沙箱环境中,默认的系统临时目录(比如/tmp)可能没有读写权限,或者动态编译工具(CSharpCodeProvider/Roslyn)默认使用的路径不被允许。你需要手动指定Unity应用有权限访问的临时目录:

1. 针对CSharpCodeProvider的修改

创建TempFileCollection时,明确指定Unity的Application.persistentDataPath作为临时目录(这个目录是应用专属的可读写路径):

// 获取Unity可访问的临时目录
string tempDir = Application.persistentDataPath + "/TempCompile";
// 确保目录存在
Directory.CreateDirectory(tempDir);

// 使用自定义临时目录创建TempFileCollection
var tempFiles = new TempFileCollection(tempDir, false);

// 初始化编译参数并指定临时文件集合
var provider = new CSharpCodeProvider();
var compileParams = new CompilerParameters
{
    TempFiles = tempFiles,
    OutputAssembly = Path.Combine(tempDir, "DynamicAssembly.dll"),
    // 添加其他必要的引用和编译选项
};

2. 针对Roslyn的修改

使用Roslyn编译时,同样要将输出路径指定到Application.persistentDataPath下的可访问目录:

string outputDir = Application.persistentDataPath + "/DynamicAssemblies";
Directory.CreateDirectory(outputDir);

var compilation = CSharpCompilation.Create(
    "DynamicAssembly",
    syntaxTrees: new[] { syntaxTree },
    references: references,
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
        .WithOutputDirectory(outputDir)
);

// 编译到指定路径
var emitResult = compilation.Emit(Path.Combine(outputDir, "DynamicAssembly.dll"));

另外,记得在Unity项目的AndroidManifest.xml中添加外部存储读写权限,确保应用能正常访问persistentDataPath目录。

二、解决最初的DLL重复引用冲突问题

你遇到的函数重复冲突,本质是另一程序编译新DLL时,把Unity导出DLL中的类型实现也打包进了新DLL,导致Unity加载时出现重复类型。解决思路是让新DLL仅引用Unity导出DLL的元数据,不包含实现:

  1. 另一程序编译时仅引用Unity DLL,不嵌入代码

    • 如果是命令行编译,确保仅通过/reference参数添加对Unity导出DLL的引用,不要将Unity DLL的代码作为项目文件包含:
      csc /target:library /reference:UnityExported.dll /out:NewDynamic.dll YourNewClass.cs
      
    • 如果是用代码编译(比如另一程序也是.NET程序),则在CompilerParameters中把Unity DLL的路径加入ReferencedAssemblies集合,不要将Unity DLL的代码加入编译源文件。
  2. 优化Unity端的DLL加载方式
    加载新DLL时,优先使用Assembly.Load(byte[])加载DLL的字节流,而非Assembly.LoadFrom,这样可以避免路径依赖问题,同时确保直接复用Unity进程中已加载的原生类型。

额外注意事项

  • Android平台上,动态生成的DLL必须放在Unity允许加载的路径下,Application.persistentDataPath是最安全的选择,不要尝试访问系统级目录。
  • 导出Unity DLL时,只包含你需要被外部调用的接口/类,不要包含Unity引擎核心类型(这些类型由Unity运行时本身提供,不需要导出),进一步降低冲突概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:16:27