Reputation: 817
I want to change the 'csproj' file of my unity project in order to be able to access a specific library as this answer sugests.
I am manually editing the file but every time i reload the project, the 'csproj' file returns to it's initial state.
Is this a common issue? Is there a way to avoid this and change the file permanently?
EDIT: My goal is to use CSharpCodeProvider so if there is another way of doing it without changing the 'csproj' file, i will gladly adopt the approach
Upvotes: 4
Views: 4815
Reputation: 1379
Just for completeness:
There is an undocumented feature in Unity which allows you to edit the generated .csproj
files (programmatically), by using an AssetPostprocessor
:
Inside any folder under Assets
named Editor
, create a class with the following structure:
public class CsprojPostprocessor : AssetPostprocessor {
public static string OnGeneratedCSProject(string path, string content) {
return PatchCsprojContent(content);
}
}
where PathCsprojContent
is a function which returns a patched version of the .csproj
file with the additions you need.
In case you want to patch only certain .csproj
files, you can check the path beforehand. For example, if you want to process only the Asset .csproj
file called Assembly-CSharp.csproj
, you can add the following check to the start of OnGeneratedCsProject
:
if (!path.EndsWith("Assembly-CSharp.csproj")) {
return content;
}
Upvotes: 3
Reputation: 817
As Suigi suggested, i have created a .dll file with the help of a .Net IDE (SharpDevelop) and just copied it in the 'Assets' folder of unity.
(How do i create a .dll file with SharpDevelop)
Here is the class that i wrote to produce the .dll file:
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;
}
}
}
}
In order to use it in any unity script, just use the namespace 'dllTest'. Then, you can call AssemblyGeneration.generateAssemblyFromCode(...) .
Upvotes: 0
Reputation: 216
As far as I know, you cannot prevent Unity from overwriting your csproj files upon recompilation of your scripts.
When working with larger code bases and Unity3D I tend to put most of my code into separate .Net assemblies (DLLs). This helps me when I'm sharing code between multiple projects and game servers, and Unity doesn't need to compile all scripts when it detects changes.
To do that fire up your .Net IDE of choice and create a new class library project (which will output a .dll). Make sure it is targeting the .Net Framework 3.5 or lower. Then, you copy the output .dll into you Unity project's Assets folder in a post-build step. I like to use a post-build step to prevent me from forgetting to copy the assembly after a change.
DLLs in the project's Assets folder are automatically referenced by Unity when it creates its C# projects. This means all of the containing code can be used from within your scripts. Note, though, that the other way around will not work as easily: you cannot use code from Unity scripts in your separate project.
Depending on what exactly you want to do with CSharpCodeProvider you can put your generation logic (and the necessary Import
directive) into such a separate project.
Edit: For more information how we set up our project structure you can watch this talk by the lead programmer on Jagged Alliance Online from Unite11.
Upvotes: 5