Unity: How to build and debug external DLLs
法一:http://forum.unity3d.com/threads/161685-How-to-build-and-debug-external-DLLs
http://docs.unity3d.com/Documentation/Manual/UsingDLL.html
法二:http://unityvs.com/documentation/dll-debugging/
We all throw dozens or hundreds of scripts into our Assets folder and let Unity build and load them. Usually this works well, but there are a number of reasons for wanting to compile at least some of your code into a DLL. This post outlines a method for building code with Visual Studio and still being able to debug it with MonoDevelop.
For context, I'm using Windows 7 64-bit, Visual C# 2010 Express, Unity 3.5.6 and MonoDevelop 2.8.2 (shipped with Unity 3.5.6). The information should apply to other versions and possibly even to Mac development, but I haven't tested it.
The basic approach is:
- create a .csproj file that uses wildcards to find all source code
- add this C# project to a Visual Studio solution
- use an MSBuild post-build target to convert Visual Studio's PDB symbols to Mono's MDB format
- debug with MonoDevelop from Unity, as normal
- source code should -not- be in the Assets folder, but the generated DLL should be
Here's a handmade .csproj file that demonstrates how this works:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- Common Properties --> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProductVersion>8.0.30703</ProductVersion> <SchemaVersion>2.0</SchemaVersion> <ProjectGuid>{61A89EEC-36B9-49ED-8431-D6A7DBDD9EA7}</ProjectGuid> <OutputType>Library</OutputType> <RootNamespace>UnityDLLExample</RootNamespace> <AssemblyName>UnityDLLExample</AssemblyName> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkProfile> </TargetFrameworkProfile> <FileAlignment>512</FileAlignment> <!-- Look up Unity install folder, and set the ReferencePath for locating managed assembly references. --> <UnityInstallFolder>$([System.IO.Path]::GetDirectoryName($(registry:HKEY_CURRENT_USER\Software\Unity Technologies\Unity Editor 3.x\Location)))</UnityInstallFolder> <ReferencePath>$(UnityInstallFolder)\Data\Managed</ReferencePath> <MonoMdbGenerator>$(UnityInstallFolder)\Data\MonoBleedingEdge\lib\mono\4.0\pdb2mdb.exe</MonoMdbGenerator> </PropertyGroup> <!-- Debug Properties --> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PlatformTarget>AnyCPU</PlatformTarget> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>Assets\Plugins</OutputPath> <DefineConstants>DEBUG;UNITY_3_5</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> <!-- Release Properties --> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PlatformTarget>AnyCPU</PlatformTarget> <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>Assets\Plugins</OutputPath> <DefineConstants>UNITY_3_5</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <PropertyGroup> <StartupObject /> </PropertyGroup> <!-- Microsoft standard stuff. --> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- Find all source --> <ItemGroup> <Compile Include="scripts\**\*.cs" /> </ItemGroup> <!-- References --> <ItemGroup> <Reference Include="System" /> <Reference Include="UnityEngine"> <Private>False</Private> </Reference> </ItemGroup> <!-- Use AfterUnityBuild from Blackbird.CSharp.targets. --> <Target Name="AfterBuild"> <CallTarget Targets="GenerateMonoSymbols" Condition=" Exists('$(OutputPath)\$(AssemblyName).pdb') " /> </Target> <Target Name="GenerateMonoSymbols"> <Message Text="$(ProjectName) -> $(TargetPath).mdb" Importance="High" /> <Exec Command=""$(MonoMdbGenerator)" $(AssemblyName).dll" WorkingDirectory="$(MSBuildProjectDirectory)\$(OutputPath)" /> </Target> </Project>
To use this build file, save it as "UnityDLLExample.csproj" in a project folder with the following layout:
-project/
-----UnityDLLExample.csproj (from this post)
-----UnityDLLExample.sln (create with Visual Studio)
-----scripts/
---------SomeScript.cs (put your source code in here, use sub-folders if you like)
-----Assets/ (Unity assets folder)
---------Plugins/ (DLL and MDB files go here)
Notes:
- MonoDevelop doesn't support the Include="**\*.cs" wildcard syntax, so you can't build this project with MonoDevelop
- you *can* build with the MSBuild command line if you don't want to open Visual Studio
- if you have editor scripts mixed in with game scripts, you can find them with Include="**\Editor\**\*.cs"
- if your editor and game scripts are inter-mixed then you need to Include the editor scripts in the editor csproj and Exclude them from the game csproj
- Unity comes with two versions of pdb2mdb.exe -- only the one in the MonoBleedingEdge folder works for coroutines (that return IEnumerator)
- for hand-building .csproj files, you can get GUIDs from http://www.guidgen.com/
This thread was started after a bunch of thought and discussion on this other thread. Thanks to @guavaman for getting the ball rolling.
Originally Posted by amirabiri
We had the same problems. Using pdb2mdb.exe from 'C:\Program Files (x86)\Unity\Editor\Data\Mono\lib\mono\2.0\pdb2mdb. exe' worked as long as we did not use IEnumerator and yield. When our *.dlls contained yield statements, pdb2mdb.exe always crashed with the following stacktrace:Originally Posted by TaiChiAnt
Code:System.ArgumentNullException: Argument cannot be null.Parametername: source
at System.Linq.Check.SourceAndPredicate (System.Object source, System.Object predicate) [0x00000] in <filename unknown>:0
at System.Linq.Enumerable.Where[PdbLines] (IEnumerable`1 source, System.Func`2 predicate) [0x00000] in <filename unknown>:0
at Pdb2Mdb.Converter.GetSourceFile (Mono.CompilerServices.SymbolWriter.MonoSymbolWriter mdb, Microsoft.Cci.Pdb.PdbFunction function) [0x00000] in <filename unknown>:0
at Pdb2Mdb.Converter.ConvertFunction (Microsoft.Cci.Pdb.PdbFunction function) [0x00000] in <filename unknown>:0
at Pdb2Mdb.Converter.Convert (Mono.Cecil.AssemblyDefinition assembly, IEnumerable`1 functions, Mono.CompilerServices.SymbolWriter.MonoSymbolWriter mdb) [0x00000] in <filename unknown>:0
at Pdb2Mdb.Driver.Convert (Mono.Cecil.AssemblyDefinition assembly, System.IO.Stream pdb, Mono.CompilerServices.SymbolWriter.MonoSymbolWriter mdb) [0x00000] in <filename unknown>:0
When switching to the other pdb2mdb.exe located at 'C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\lib\mono\ 4.0\pdb2mdb.exe', it worked for some of our PCs but crashed on others with the error given by amirabiri. Doing some research we found that this is related to the mono version used to execute pdb2mdb.exe. We could fix this issue by using the mono.exe located at 'C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\bin\mono. exe'. The command looks like (make sure the cwd is where the dll is located)
Code:"C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe" "C:\Program Files (x86)\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.0\pdb2mdb.exe" Your.dll
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2012-05-09 [转]Free Game Development Libraries
2012-05-09 [转]刨根问底!曲面细分技术到底是个啥?