如何在Unity中使用共享C#项目?实现外部项目自动关联
这个场景我太熟悉了——Unity自动重建项目文件的特性确实会搞砸外部项目的直接关联,手动复制DLL又烦得要死。下面给你几个经过实践验证的自动化方案,按需选择:
方案1:用Unity Package Manager导入本地包(推荐)
这是最贴合Unity生态的方式,既能自动同步DLL,又不会被Unity的项目重建影响。
步骤:
- 给Shared类库设置固定的输出路径,比如相对于解决方案根目录的
../SharedPackage/Plugins(这个路径要在Unity项目外部,避免Unity误处理)。 - 在
SharedPackage文件夹下创建package.json文件,内容如下(修改成你的公司/项目标识):
{ "name": "com.yourcompany.shared", "version": "1.0.0", "displayName": "Shared Core Library", "description": "Shared business logic between Server and Unity Client", "dependencies": {} }
- 打开Unity,在Package Manager面板点击
+→Add package from disk...,选择刚才创建的package.json。Unity会自动识别这个本地包并加载里面的DLL。 - 给Shared类库添加Post-build事件,让每次构建完成后自动把DLL复制到
SharedPackage/Plugins:- 右键Shared类库项目 → 属性 → 生成事件 → 后期生成事件命令行,输入:
(copy "$(TargetPath)" "$(SolutionDir)SharedPackage\Plugins\$(TargetFileName)" copy "$(TargetPdb)" "$(SolutionDir)SharedPackage\Plugins\$(TargetPdb)"$(SolutionDir)是MSBuild的内置宏,自动指向解决方案根目录,不用写死路径)
这样每次你构建Shared类库,Unity的Package Manager会自动检测到文件更新,无需手动操作。
方案2:用MSBuild自动复制DLL到Unity Assets
如果不想折腾Package Manager,直接用构建脚本自动复制也是个简单有效的办法——我们不修改Unity的项目文件,只复制DLL到Assets文件夹,Unity会自动识别并引用它。
步骤:
- 同样给Shared类库添加Post-build事件,直接把DLL复制到Unity项目的
Assets/Plugins文件夹:
(把copy "$(TargetPath)" "$(SolutionDir)Client\Assets\Plugins\$(TargetFileName)" copy "$(TargetPdb)" "$(SolutionDir)Client\Assets\Plugins\$(TargetPdb)"Client换成你的Unity项目文件夹名) - 可选优化:在Unity的
Edit → Project Settings → Editor里,开启Enter Play Mode Settings并关闭Reload Domain,这样DLL更新后不用重新加载整个脚本域,调试效率更高。
方案3:Unity编辑器脚本自动同步
写个轻量的编辑器脚本,让Unity自动检测Shared DLL的更新并同步,适合需要手动触发或者自动在Unity启动时同步的场景。
步骤:
- 在Unity项目的
Assets/Editor文件夹下创建SharedLibrarySync.cs脚本(Editor文件夹是Unity的特殊文件夹,里面的脚本只会在编辑器运行):
using UnityEngine; using UnityEditor; using System.IO; public class SharedLibrarySync : EditorWindow { // 改成你的Shared DLL实际输出路径 private string sharedDllPath = @"../Shared/bin/Debug/shared.dll"; // Unity项目内的目标路径 private string targetPath = "Assets/Plugins/shared.dll"; [MenuItem("Tools/Sync Shared Library")] public static void OpenSyncWindow() { GetWindow<SharedLibrarySync>("Sync Shared Lib"); } private void OnGUI() { sharedDllPath = EditorGUILayout.TextField("Shared DLL Path", sharedDllPath); targetPath = EditorGUILayout.TextField("Target Path", targetPath); if (GUILayout.Button("Sync Now")) { PerformSync(); } } private void PerformSync() { if (!File.Exists(sharedDllPath)) { Debug.LogError($"Shared DLL not found at: {sharedDllPath}"); return; } string fullSourcePath = Path.GetFullPath(sharedDllPath); string fullTargetPath = Path.GetFullPath(targetPath); // 只有当源文件更新时间晚于目标文件时才复制 if (File.GetLastWriteTime(fullSourcePath) > File.GetLastWriteTime(fullTargetPath)) { File.Copy(fullSourcePath, fullTargetPath, true); AssetDatabase.Refresh(); Debug.Log("Successfully synced Shared Library!"); } else { Debug.Log("Shared Library is already up to date."); } } // 可选:Unity启动时自动同步 [InitializeOnLoadMethod] private static void AutoSyncOnUnityLoad() { var syncWindow = GetWindow<SharedLibrarySync>(); syncWindow.PerformSync(); } }
- 保存脚本后,Unity会编译它,你可以通过顶部菜单
Tools → Sync Shared Library打开窗口手动同步,或者依赖InitializeOnLoadMethod让Unity启动时自动同步。
关键注意事项
- 绝对不要直接修改Unity生成的
.csproj文件——Unity每次刷新项目(比如添加/删除Asset、修改Player设置)都会重建这个文件,你的所有手动修改都会被覆盖。 - 确保Shared类库的目标框架和Unity兼容:比如Unity 2022+通常推荐
.NET Standard 2.0或者.NET Framework 4.x,在Shared类库的项目属性里设置正确的目标框架,避免DLL加载失败。 - 如果需要调试Shared类库的代码:在Unity的
Edit → Project Settings → Player里设置正确的Scripting Runtime Version,然后在Visual Studio里通过Debug → Attach to Process选择Unity进程,就能直接调试Shared类库的代码了。
内容的提问来源于stack exchange,提问作者Alde




