快速摘要
把 Unity 腳本編成獨立 .dll,通常是為了跨專案重用或封裝穩定 API。本文整理目前較穩的做法:先對齊 Unity 的 API 相容層級,再在 .NET 類別庫中引用需要的 Unity 組件,最後自動把輸出的 .dll 複製回 Unity 專案。
![]()
把 Unity 腳本編成獨立 .dll,通常是在兩種情況下才真的值得做。第一種是你手上有一批很穩的工具,想跨專案重用;第二種是你想把對外 API 和內部實作切開,讓 Unity 專案端只看到該看的介面。這條路確實有價值,但它也會帶來版本管理、相依組件和除錯方式的成本,先把這個前提講清楚,比較不會一開始就把 .dll 當成萬用解法。
本文談的是 Runtime 用的 managed plug-in,也就是最後會被 Unity 當成受控外掛載入的 .dll。Unity 官方對這類檔案的載入方式與限制,請參考:Managed plug-ins。
先建立一個獨立的 .NET 類別庫
先準備一個空資料夾,然後在這個資料夾裡建立新的類別庫專案:
1dotnet new classlib
建立完成後,資料夾裡會看到預設的 .csproj、Class1.cs 和 obj 目錄。這裡建的是標準 .NET 類別庫,還沒有任何 Unity 相依。
如果你平常就是用 VS Code 寫 Unity 腳本,這個專案一樣可以直接用 Unity 6 VS Code 設定:修正 C# 自動完成失效與專案同步 那篇的方式開發。
先對齊 Unity 專案的 API 相容層級
這一步比很多人想得重要。獨立類別庫的目標框架,最好先和 Unity 專案的 API Compatibility Level 對齊。以 Unity 6 目前的預設來看,新的專案通常會落在 .NET Standard 2.1;Unity 官方的文件也明確把 .NET Standard 2.1 列為目前支援的 API Profile。請參考:API profile support。
因此,新的 .csproj 通常會先改成這樣:
1<Project Sdk="Microsoft.NET.Sdk">
2
3 <PropertyGroup>
4 <TargetFramework>netstandard2.1</TargetFramework>
5 <RootNamespace>unity_dll_dev</RootNamespace>
6 </PropertyGroup>
7
8</Project>
如果你的 Unity 專案還是舊版設定,就不要硬套 netstandard2.1。先回 Unity 看實際的 API Compatibility Level,再把類別庫跟著對齊,這樣比較穩。
引用真正需要的 Unity 組件
接下來才是關鍵。獨立的 .NET 類別庫不會自帶 MonoBehaviour、GameObject 或 Transform,所以必須把對應的 Unity 組件手動引用進來。
很多舊教學會直接寫 UnityEngine.dll。這個說法現在太粗了。Unity 官方文件的做法,是到 Editor 安裝目錄底下的 Data/Managed/UnityEngine 找你需要的組件,例如最基本的 UnityEngine.CoreModule.dll。如果你要用的是 UnityEngine.UI 這類額外命名空間,還要再補對應的組件。請參考:Create and use a DLL。
先找到 Unity Editor 的安裝位置。從 Unity Hub 切到「安裝」,在對應版本右側打開管理選單,選「在檔案總管中顯示」,就能看到 Editor 所在目錄。

以 Windows 為例,路徑通常會長這樣:
1F:\UnityEditors\6000.0.0f1\Editor
那 MonoBehaviour、GameObject 這些最核心型別所在的組件,常見位置會是:
1F:\UnityEditors\6000.0.0f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
接著把 .csproj 改成下面這樣:
1<Project Sdk="Microsoft.NET.Sdk">
2
3 <PropertyGroup>
4 <TargetFramework>netstandard2.1</TargetFramework>
5 <RootNamespace>unity_dll_dev</RootNamespace>
6 </PropertyGroup>
7
8 <ItemGroup>
9 <Reference Include="UnityEngine.CoreModule">
10 <HintPath>F:\UnityEditors\6000.0.0f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll</HintPath>
11 </Reference>
12 </ItemGroup>
13
14</Project>
這個起點足夠讓我們在類別庫裡使用 MonoBehaviour、GameObject、Transform 這些核心型別。若之後用到 UnityEngine.UI、TextMeshPro 或其他套件命名空間,再依實際編譯錯誤去補相對應的組件,不要一開始就把整包 DLL 全塞進來。
在類別庫裡寫 Unity 可用的程式
組件接好後,就能在 Class1.cs 裡改寫自己的功能。你可以把它寫成一般工具類別,也可以直接讓類別繼承 MonoBehaviour,讓 Unity 之後把它當成元件掛到物件上。

這邊我會建議先從小的 Runtime 功能開始,像是工具類別、共用邏輯、資料處理,或少量會掛到場景物件上的元件。越依賴場景、序列化和 Editor 工作流的腳本,搬到 .dll 之後的維護成本越明顯。
先用 build 產出 .dll
本文的目標只是拿到可給 Unity 用的 .dll,直接編譯即可:
1dotnet build -c Release
輸出的 .dll 會出現在 bin/Release/netstandard2.1/。把這個檔案複製到 Unity 專案的 Assets 底下即可,放在 Assets/Plugins 只是比較常見、也比較好管理的做法。Unity 官方文件同樣是用 Assets 底下的 managed plug-in 來說明。
如果你的類別繼承 MonoBehaviour,Unity 也能把這個 .dll 裡的腳本視為可掛載元件。

把編譯後的 .dll 自動複製回 Unity
每次手動複製 .dll 很快就會煩。比較實際的做法,是讓 .csproj 在編譯完成後直接把檔案複製回 Unity 專案。
可以在 .csproj 裡加上一個 AfterTargets="Build" 的 Target:
1<Target Name="CopyToUnityProject" AfterTargets="Build">
2 <Copy
3 SourceFiles="$(OutDir)$(TargetName).dll"
4 DestinationFolder="..\TestDLL\Assets\Plugins" />
5</Target>
DestinationFolder 請改成你自己的 Unity 專案路徑,可以用相對路徑,也可以用絕對路徑。這樣之後每次跑 dotnet build -c Release,新的 .dll 就會直接更新到 Unity 專案裡。
如果你有多個輸出檔,或還需要一併複製相依 .dll,再往這裡加規則即可。本文先把最小路徑走通。
用 VS Code 快捷鍵加速日常編譯
如果你平常就在 VS Code 裡維護這個類別庫,可以把 dotnet build -c Release 綁到預設 Build Task。做法是在專案裡建立 .vscode/tasks.json:
1{
2 "version": "2.0.0",
3 "tasks": [
4 {
5 "label": "Build DLL",
6 "type": "shell",
7 "command": "dotnet build -c Release",
8 "group": {
9 "kind": "build",
10 "isDefault": true
11 },
12 "presentation": {
13 "reveal": "always"
14 }
15 }
16 ]
17}
設定好之後,按 Ctrl + Shift + B 就能直接編譯。若 .csproj 也加了自動複製規則,那這個快捷鍵就等於一邊編譯、一邊把新的 .dll 推回 Unity。
總結
把 Unity 腳本編成獨立 .dll,真正的關鍵不在「能不能編出一個檔案」,而在於路徑要走對。先對齊 Unity 專案的 API Compatibility Level,再只引用真正需要的 Unity 組件,接著用 dotnet build 產出 .dll,最後把更新流程自動化。這樣做,跨專案重用和封裝 API 才真的有機會變成優勢,而不是多一層維護負擔。
如果這套 .dll 會長期跨專案使用,下一步就值得再整理版本號、發布流程和相依管理。若它只服務單一專案,而且會頻繁改動,先留在 Unity 專案內直接開發,通常反而比較省事。
常見問題
MonoBehaviour、GameObject、Transform 這些型別屬於 Unity 的組件,獨立的 .NET 類別庫本來不會自帶。先把對應的 Unity 組件引用進來,編譯器才認得這些型別。dotnet build -c Release 就夠了。dotnet pack 更偏向包成 NuGet 套件,這篇先不把流程拉到那麼大。