每次重新加载项目时,Unity 中的 Csproj 文件都会更改

本文关键字:Csproj 中的 Unity 文件 新加载 项目 加载 | 更新日期: 2023-09-27 17:56:49

我想更改我的 Unity 项目的"csproj"文件,以便能够访问特定的库,因为这个答案是这个答案。

我正在手动编辑文件,但每次重新加载项目时,"csproj"文件都会返回到其初始状态。

这是一个常见问题吗?有没有办法避免这种情况并永久更改文件?


编辑:我的目标是使用CSharpCodeProvider,所以如果有另一种方法可以在不更改"csproj"文件的情况下做到这一点,我很乐意采用这种方法

每次重新加载项目时,Unity 中的 Csproj 文件都会更改

据我所知,您无法阻止 Unity 在重新编译脚本时覆盖您的 csproj 文件。

在使用较大的代码库和 Unity3D 时,我倾向于将大部分代码放入单独的 .Net 程序集 (DLL) 中。当我在多个项目和游戏服务器之间共享代码时,这对我很有帮助,并且 Unity 在检测到更改时不需要编译所有脚本。

为此,请启动您选择的 .Net IDE,并创建一个新的类库项目(将输出一个.dll)。确保它面向 .Net Framework 3.5 或更低版本。然后,在后期构建步骤中将输出.dll复制到 Unity 项目的"资源"文件夹中。我喜欢使用构建后步骤来防止我在更改后忘记复制程序集。

Unity 在创建其 C# 项目时会自动引用项目的"资产"文件夹中的 DLL。这意味着所有包含的代码都可以在脚本中使用。但请注意,反之则不那么容易:您不能在单独的项目中使用 Unity 脚本中的代码。

根据你想用CSharpCodeProvider做什么,你可以把你的生成逻辑(和必要的Import指令)放到这样一个单独的项目中。

编辑:有关我们如何设置项目结构的更多信息,您可以观看Unite11的Jagged Alliance Online首席程序员的演讲。

只是为了完整起见:

Unity 中有一个未记录的功能,它允许您使用AssetPostprocessor(以编程方式)编辑生成的.csproj文件:

在名为 Editor Assets 下的任何文件夹中,创建一个具有以下结构的类:

public class CsprojPostprocessor : AssetPostprocessor {
        public static string OnGeneratedCSProject(string path, string content) {
            return PatchCsprojContent(content);
        }
    }

其中PathCsprojContent是一个函数,它返回.csproj文件的修补版本,其中包含您需要的添加内容。

如果您只想修补某些.csproj文件,您可以事先检查路径。例如,如果只想处理名为 Assembly-CSharp.csproj 的资产.csproj文件,则可以在OnGeneratedCsProject的开头添加以下检查:

if (!path.EndsWith("Assembly-CSharp.csproj")) {
    return content;
}

参考资料:https://learn.microsoft.com/en-us/visualstudio/gamedev/unity/extensibility/customize-project-files-created-by-vstu

正如Suigi所建议的那样,我在.Net IDE(SharpDevelop)的帮助下创建了一个.dll文件,并将其复制到unity的"Assets"文件夹中。

(如何使用锐化创建.dll文件)

这是我为生成.dll文件而编写的类:

using System;
using System.Collections.Generic;
using System.CodeDom.Compiler;
using System.Diagnostics;
using Microsoft.CSharp;
using System.Reflection;
namespace dllTest {
public class AssemblyGeneration {
    public static Assembly generateAssemblyFromCode(string code, string assemblyFilename) {
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
        parameters.GenerateExecutable = false;
        parameters.OutputAssembly = assemblyFilename + ".dll";
        CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, code);
        Assembly assembly = null;
        if (!results.Errors.HasErrors) {
            assembly = results.CompiledAssembly;
            return assembly;
        }
        else {
            return null;
        }
    }
}
}

为了在任何统一脚本中使用它,只需使用命名空间'dllTest'。然后,你可以调用AssemblyGeneration.generateAssemblyFromCode(...)。