msbuild(CLI)编译Unity项目时跨程序集引用损坏问题如何解决?
问题成因
- 核心原因是Unity自动生成的.csproj文件中,跨程序集的
<ProjectReference>节点默认添加了ReferenceOutputAssembly="False"属性。这个属性的作用是仅向IDE声明项目依赖关系,实际编译时不会将依赖项目的输出程序集添加到当前项目的编译引用列表中。因此即便msbuild识别到依赖先完成了A程序集的编译,编译B时也找不到A的类型定义,出现CS0103、CS0246、CS0234这类找不到类型/命名空间的错误。 - 次要成因包括:使用了未更新的旧csproj文件、单独编译单个csproj时依赖输出路径未被正确识别、系统安装的mono版本与Unity使用的.NET目标框架版本不兼容。
解决方案
- 第一步:添加Unity编辑器脚本自动修正csproj属性。将以下脚本放入项目的
Assets/Editor目录下,Unity生成csproj时会自动将所有项目引用的ReferenceOutputAssembly改为True,确保编译时会引入依赖程序集:
using UnityEditor; using System.IO; using System.Xml.Linq; public class CsprojReferenceFixer : AssetPostprocessor { public static string OnGeneratedCSProject(string path, string content) { var doc = XDocument.Parse(content); XNamespace msbuildNs = "http://schemas.microsoft.com/developer/msbuild/2003"; foreach (var projRef in doc.Descendants(msbuildNs + "ProjectReference")) { var refOutputAttr = projRef.Attribute("ReferenceOutputAssembly"); if (refOutputAttr != null) { refOutputAttr.Value = "True"; } else { projRef.Add(new XAttribute("ReferenceOutputAssembly", "True")); } } using var strWriter = new StringWriter(); doc.Save(strWriter); return strWriter.ToString(); } }
- 第二步:CI流程中编译前先执行Unity命令行生成最新的解决方案文件,避免使用过时的csproj:
Unity -quit -batchmode -projectPath ${你的项目根路径} -executeMethod UnityEditor.SyncVS.SyncSolution
- 第三步:调整msbuild编译命令,直接编译完整的.sln解决方案而非单个csproj,确保所有依赖路径正确解析:
# 替换为你的项目生成的sln文件名,一般和项目根目录同名 msbuild YourProject.sln -t:Rebuild -p:Configuration=Release
- 额外校验:确认你的Docker镜像中安装的mono-devel版本支持Unity使用的.NET框架版本(如Unity 2020+默认使用.NET Framework 4.x,对应mono版本至少为6.x以上)。
内容的提问来源于stack exchange,提问作者IARI
相关产品推荐
相关产品推荐

