Skip to content

Instantly share code, notes, and snippets.

Created June 11, 2017 17:29
Show Gist options
  • Save anonymous/9da0afc02257e93864542af90f7420c8 to your computer and use it in GitHub Desktop.
Save anonymous/9da0afc02257e93864542af90f7420c8 to your computer and use it in GitHub Desktop.
Enables easier use of external class libraries and other VS projects with Unity.
/// <summary>
/// Trying to reference another Visual Studio project (for example a class library with core functionality) in your Unity3D project usually does not work.
/// You can add the project to your VS solution, but you still need to copy the compiled DLL to Unity in order to use it. An exemplary copy instruction in the post-build event command line might look like this:
///
/// xcopy /C /Y /R "$(ProjectDir)bin\Debug\MyProjectName.dll" "$(ProjectDir)..\MyProjectUnityFolder\Assets\"
///
/// When Unity autogenerates its project files for Visual Studio, it only adds a reference to the compiled dll that you have built and copied.
/// Unity does not care about the original project and neither does Visual Studio when you make changes to the Unity3D project itself.
/// This means you cannot use various meta related editor actions like go to definition, refactor etc. in the class library. The Unity3D source files will not be affected.
///
/// The following script ties into the build process of Unity. Just add this script to an Editor folder directly in your Unity3D project.
/// Whenever you now load the project in Visual Studio, it will only see the project reference while Unity itself will still use the DLL.
/// The script will automatically exchange the reference to the DLL file with a reference to the csproj file whenever the Visual Studio project files are regenerated.
/// This gives you the ability to edit the entire solution more easily.
///
/// Original thread to this topic: https://forum.unity3d.com/threads/how-to-find-all-method-references-in-visual-studio-2015-from-compiled-referenced-dll-in-unity.459867/
/// </summary>
public class ReferenceExchange : AssetPostprocessor
{
public class ReferenceExchangeMeta
{
/// <summary>
/// Project name.
/// </summary>
public string ProjectName;
/// <summary>
/// Project guid (from the csproj file).
/// </summary>
public string TargetProjectGuid;
/// <summary>
/// Relative path to the project which will be used as the project reference.
/// </summary>
public string TargetProjectPath;
public ReferenceExchangeMeta(string projectName, string targetProjectGuid, string targetProjectPath)
{
ProjectName = projectName;
TargetProjectGuid = targetProjectGuid;
TargetProjectPath = targetProjectPath;
}
}
/// <summary>
/// List of references that will be swapped out.
/// </summary>
public static ReferenceExchangeMeta[] References = new ReferenceExchangeMeta[]
{
new ReferenceExchangeMeta ("MyProjectName", "MyProjectGuidWithNoBraces", @"MyProjectRelativePath") // e.g. ("MyProject", "35ec7784-734f-4b3c-a4dc-a39198549624", @"..\MyProjectDir\MyProject.csproj")
};
public static void OnGeneratedCSProjectFiles()
{
var projectDirectory = Directory.GetParent(Application.dataPath).FullName;
var projectName = Path.GetFileName(projectDirectory);
var csProjFile = Path.Combine(projectDirectory, string.Format("{0}.csproj", projectName));
try
{
// read, change and overwrite the csproj file in here
var content = File.ReadAllText(csProjFile);
foreach (var referenceEntry in References)
{
var regex = string.Format(@"<Reference Include=\""{0}\"">(.|\n)*<\/Reference>", referenceEntry.ProjectName);
// Remove the original file reference
content = Regex.Replace(content, regex, "");
// Find the project reference tag.
var index = content.IndexOf("<ProjectReference", StringComparison.Ordinal);
if (index != -1)
{
var newReference = @"<ProjectReference Include=""" + referenceEntry.TargetProjectPath + @""">" + Environment.NewLine +
" <Project>{" + referenceEntry.TargetProjectGuid + "}</Project> " + Environment.NewLine +
" <Name>" + referenceEntry.ProjectName + "</Name>" + Environment.NewLine +
" </ProjectReference>" + Environment.NewLine +
" ";
content = content.Insert(index, newReference);
}
}
File.WriteAllText(csProjFile, content);
}
catch (Exception e)
{
Debug.Log("Project file could not be changed.");
Debug.Log(e.Message);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment