在 Unity 解决方案中引用外部工程(.csproj)或 NuGet 包

这篇具有很好参考价值的文章主要介绍了在 Unity 解决方案中引用外部工程(.csproj)或 NuGet 包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

本人近期制作一服务端和客户端程序,采用下列架构实现:

  • 服务端(Server.exe)
  • 中间件(Shared.dll,实现两端共享的那部分代码)
  • 客户端(Client.exe,用 Unity 实现)

在不使用 Unity 的情况下,一般把三个工程(.csproj)放入同一解决方案(.sln),然后在服务端和客户端添加对中间件的引用即可。但是,现在用 Unity 实现客户端,Unity 的解决方案不支持引入外部工程或 NuGet 包,强行引入会在 Build 时被删掉。

自然会想到,将中间件的代码或 dll 每次手动放入客户端,但这样除了操作麻烦、版本管理不便等问题之外,还会出现 Unity 不能检测到文件更新等诸多罗乱。由此,本人才另寻他法。

在 Unity 中引入外部工程或 NuGet 包

简单来说,使用此工具 MSBuildForUnity(msb4u),按其说明文档来操作即可。喜欢阅读生肉的朋友可以关闭本文,因为文本的出发点只是对其稍作整理和说明,供自己查阅方便。
工具地址:https://github.com/microsoft/MSBuildForUnity

步骤 1:将 msb4u 引入 Unity

  1. 编辑 Unity 工程中的 Packages/manifest.json,遵循 json 语法,与 "dependencies" 同级,并在其上方添加下列内容:
  "scopedRegistries": [
    {
        "name": "Microsoft",
        "url": "https://pkgs.dev.azure.com/UnityDeveloperTools/MSBuildForUnity/_packaging/UnityDeveloperTools/npm/registry/",
        "scopes": [
            "com.microsoft"
        ]
    }
  ],
  1. "dependencies" 的下级中添加下列内容:
"com.microsoft.msbuildforunity": "<version>",

其中,<version> 换成 这里 所提供的最新版(“@”后面那个就是版本号)。

弄好以后如下所示,保存。回到 Unity,Unity 会自动引入 msb4u,并弹出一些介绍和设置,关闭即可。

{
  "scopedRegistries": [
    {
        "name": "Microsoft",
        "url": "https://pkgs.dev.azure.com/UnityDeveloperTools/MSBuildForUnity/_packaging/UnityDeveloperTools/npm/registry/",
        "scopes": [
            "com.microsoft"
        ]
    }
  ],
  "dependencies": {
    "com.microsoft.msbuildforunity": "0.9.2-20221114.1",
    "com.unity.collab-proxy": "1.15.16",
    "com.unity.feature.2d": "1.0.0",
    "com.unity.ide.rider": "3.0.13",
    "      (后面省略)    ": ""
  }
}

步骤 2:添加引用

Unity 已经创建了下列文件:

  • Asset/{Unity工程名称}.Dependencies.msb4u.csproj
  • Asset/NuGet.config

在 Unity 外部使用文本编辑器修改 Asset/{Unity工程名称}.Dependencies.msb4u.csproj

<Project ToolsVersion="15.0">
<!--GENERATED FILE-->
<!--
    This file can be modified and checked in.
    
    It is different from the other generated C# Projects in that it will be the one gathering all dependencies and placing them into the Unity asset folder.
    
    You can add project level dependencies to this file, by placing them below:
    - <Import Project="$(MSBuildForUnityGeneratedProjectDirectory)\$(MSBuildProjectName).g.props" />
    and before:
    - <Import Project="$(MSBuildForUnityGeneratedProjectDirectory)\$(MSBuildProjectName).g.targets" />
    
    Do not add any source or compilation items.
    
    Examples of how you can modify this file:
    - Add NuGet package references:
        <ItemGroup>
            <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
        </ItemGroup>
    - Add external C# project references:
    <ItemGroup>
        <ProjectReference Include="..\..\..\ExternalLib\ExternalLib.csproj" />
    </ItemGroup>
-->

<Import Project="$([MSBuild]::GetPathOfFileAbove(MSBuildForUnity.Common.props))" Condition="Exists('$([MSBuild]::GetPathOfFileAbove(MSBuildForUnity.Common.props))')" />

<PropertyGroup>
    <TargetFramework>$(UnityCurrentTargetFramework)</TargetFramework>
</PropertyGroup>

<!-- SDK.props is imported inside this props file -->
<Import Project="$(MSBuildForUnityGeneratedProjectDirectory)\$(MSBuildProjectName).g.props" />

<ItemGroup>
    <!--Add NuGet or Project references here-->
    
    <!-- 注意这里 -->
    <!-- 注意这里,按照上方注释中的例子添加对外部工程或 NuGet 包的引用 -->
    <!-- 注意这里 -->
        
</ItemGroup>

<!-- SDK.targets is imported inside this props file -->
<Import Project="$(MSBuildForUnityGeneratedProjectDirectory)\$(MSBuildProjectName).g.targets" />
</Project>

注意在其中的 <ItemGroup> 标签内,按照上方注释中的例子添加对外部工程或 NuGet 包的引用。例如:

<ItemGroup>
    <!-- 引用外部工程 -->
    <ProjectReference Include="..\..\..\ExternalLib\ExternalLib.csproj" />
    <!-- 引用 NuGet 包 -->
    <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
</ItemGroup>

保存,回到 Unity。此时很可能 Unity 会报错,这个后文再说。正常情况下,以后点击菜单中的 MSBuild -> Build All Projects,msb4u 就会先把外部工程或 NuGet 包首先生成到下列位置:

  • Assets\Dependencies\netstandard2.0\

然后再通知 Unity 进行 Build。这之后,Unity 的解决方案(.sln)相当于已经添加了对(最新的)外部工程或 NuGet 包的引用,我们便可以在代码中使用它们了。

这些已经基本解决了本人的需求,所以没有进行更深入的研究。其实 MSBuildForUnity 还提供了几个例子,涉及到两个 Unity 工程之间互相引用、跨平台等复杂问题,详细了解请阅读原文。

步骤 3:解决报错

第二步做完后,Unity 很可能会报告下列错误:

  • Unable to find package Microsoft.Build.NoTargets
  • Error MSB4236: The SDK ‘Microsoft.Build.NoTargets/1.0.85’ specified could not be found.
  • 其他 SDK 版本错误字样

此问题可参考 Issue #153:https://github.com/microsoft/MSBuildForUnity/issues/153
这里简单总结如下。

主要原因:

  • 外部工程或 NuGet 包的框架版本不是 .NET Core 2.1 的(或者 .NetStandard 2.0,不确定)
  • msb4u 尚未缓存 build 其他版本框架所需的组件

解决步骤:

  1. 在 Unity 外部使用文本编辑器修改 Assets\NuGet.config,注释掉其中的 <clear /> 标签,如下:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <!-- <clear /> -->
    <add key="MSBuildForUnity" value="https://pkgs.dev.azure.com/UnityDeveloperTools/MSBuildForUnity/_packaging/UnityDeveloperTools/nuget/v3/index.json" />
  </packageSources>
</configuration>
  1. 在 Unity 工程的任意位置创建一个 global.json,写入下列内容:
{
  "sdk": {
    "version": "2.1.202"
  }
}

其中,2.1.202 修改为外部工程或 NuGet 包的框架版本的字符串。外部工程的版本字符串可以用文本编辑器打开其工程文件(.csproj),找到 TargetFrameworkVersion 标签,例如:

<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>

其中的 v4.7.2 即为所需。NuGet 包的版本字符串应该可以在 NuGet 包管理器页面中很容易地见到,不过一般来说 NuGet 包的版本比较全,可能不容易造成 Unity 报错。

  1. 回到 Unity,重新尝试 MSBuild -> Build,应该已经能够 Build 成功,不再报错。这时,msb4u 已经缓存了 build 该版本框架所需的组件(可能是位于 MSBuild\ 中的那些文件),因此前面两步的修改可以回滚,也就是:
  • 删除 global.json
  • 取消 Assets\NuGet.config 中对 <clear /> 标签的注释

注:不需要改变外部工程的框架版本,如果笔者没理解错的话。

参考资料

为了找到最佳的方法,笔者查阅了大量资料。本文所提到的方法应该并不唯一,这里把相关信息(仅一部分)也列举出来,以供参考。

极为相关的:

  1. MSBuildForUnity: https://github.com/microsoft/MSBuildForUnity
  2. MSBuildForUnity - IntegratedDependencies: https://github.com/microsoft/MSBuildForUnity/blob/master/Samples/IntegratedDependencies.Unity/README.md
  3. MSBuildForUnity Introduction: https://stackoverflow.com/a/67009872

有帮助的:文章来源地址https://www.toymoban.com/news/detail-430989.html

  1. 选择要使用的 .NET 版本及 global.json 语法:https://learn.microsoft.com/zh-cn/dotnet/core/versions/selection
  2. Use Package Manager to host and add your own Custom Packages as a dependency:
    https://stackoverflow.com/a/62402865
  3. Use git submodule: https://stackoverflow.com/a/73839806
  4. Use git submodule: https://stackoverflow.com/a/45365163
  5. Use source (code version) control: https://forum.unity.com/threads/referencing-another-project-in-visual-studio.504115/
  6. Use source (code version) control: https://answers.unity.com/questions/16908/how-to-share-c-source-between-unity-projects.html
  7. Use Visual Studio Tools: http://devleader.ca/2015/02/08/multiple-c-projects-unity-3d-solution/
  8. Use Assembly Definition files (.asmdef): https://stackoverflow.com/a/38413222

到了这里,关于在 Unity 解决方案中引用外部工程(.csproj)或 NuGet 包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android13关于获取外部存储文件的相关问题及解决方案记录

      Android的学习路上... 测试设备:vivo X90s 安卓版本: Android13 开发环境:AndroidStudio Flamingo SDK:33 最近我在Android13的环境下尝试写一个 文件选择器 ,以便日后的开发使用。但是我们知道,从Android13 (API33) 开始,外部存储权限发生了变化,要想读取外部存储文件,使用原来的权

    2024年01月15日
    浏览(66)
  • 外部navicat无法连接mysql数据库的问题原因及解决方案

    问题起因是这样:在linux操作中的docker中部署了一个数据库,数据库启动之后,端口也映射了(创建容器时用 -p 30036:3306进行的映射),但是在外不想使用navicat连接时,怎么都连不上,本人遇到的问题如下 一、端口虽然映射了,但是服务器上的30036端口并未对外开放,因此要先开

    2024年02月07日
    浏览(56)
  • 解析C++链接错误:未定义引用和未解析符号的完整解决方案

      概述: C++中的\\\"未定义的引用\\\"和\\\"未解析的外部符号\\\"错误通常源于声明与定义不一致或缺失定义。解决方法包括确保所有声明有相应定义、检查定义位置,使用头文件和命名空间组织代码。这些步骤帮助开发者提高代码可维护性和避免链接错误。 在C++中,\\\"未定义的引用\\\"和

    2024年03月20日
    浏览(51)
  • 【解决方案】‘python‘ 不是内部或外部命令,也不是可运行的程序或批处理文件

    有时候,在 cmd 中输入 python,会提醒 ‘python’ 不是内部或外部命令,也不是可运行的程序或批处理文件。 我将python安装在E盘之后,输入python,显示如下问题 这个问题本质其实就是,windows的cmd并不能识别python这个符号(即无法识别这个符号是一个可执行程序),因为windows这

    2024年02月14日
    浏览(63)
  • VS2022迁移VS2019项目遇到的.Net Framework 引用程序集问题解决方案

    在GitHub上发现TrafficMonitor的开源代码,想要自己过一遍这个项目 在VS2022上面打开出现了MSB3644错误,打开微软 “找不到项目所请求 .NET 版本的 .NET 引用程序集时,会发生此错误。 发生此问题的原因可能是项目文件存在问题,它所请求的版本无法识别或未安装;也可能是安装问

    2024年02月06日
    浏览(109)
  • Modelsim恢复编辑器的解决方案——只能将外部编辑器删除后,重新匹配编辑器

    1,Modelsim和Questasim是相互兼容的,配置的编辑器变成了sublime,且更换不了编辑器 2,解决问题的方案,还是没得到解决 在网上搜索了:Modelsim如何恢复默认编辑器。类似相关的文档,都没有得到解决。 主要参考文献: 1,modelsim更改默认编辑器以及恢复默认编辑器 上述文章,

    2024年02月13日
    浏览(64)
  • Aurora的工程化问题解决方案

    ​针对Aurora在实际工程的例化应用问题上,本人经过以往经验进行可行性方案分享,其中有关Aurora的例化过程及不进行详细介绍,可自行查询其他博客学习,望补充指正,谢谢。 (补充:该文里的aurora默认为全双工模式) ​本文主要阐述Aurora协议在多通道例化上的应用问题

    2024年02月07日
    浏览(35)
  • 通过cmake工程生成visual studio解决方案

    visual studio是一个很强大的开发工具,这个工具主要是通过解决方案对我们的源码进行编译等操作。但是我们很多时候拿到的可能并不是一个直接的解决方案,可能是是一个cmake工程,那么这个时候我们就需要通过cmake工程生成解决方案,然后就可以通过visual studio进行编译和调

    2024年02月15日
    浏览(47)
  • 【入门级图文教程】在Visual Studio中创建自定义Winform控件库并在其他解决方案中引用

    目录 本教程使用到的相关软件或产品: 教程正文:         创建用户控件库:         添加自定义控件项:         在其他解决方案中引用: Windows 10 专业版        10.0.19044 Microsoft Visual Studio Community 2022 (64 位)  版本17.3.2 「.NET 桌面开发」工作负荷(在开始菜单

    2024年02月10日
    浏览(51)
  • Vivado打开的工程文件的中文注释出现乱码解决方案

    有同学在使用vivado打开一些工程的时候,发现其中注释有乱码,现象如下图: 原因分析: 有的工程是从其他编码软件中移植而得,而工程V文件源码的代码部分在代码编辑软件中是可以通用的,由于注释部分含有中文,两款EDA软件对中文的字符编码格式不同,在工程移植到

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包